尝试从程序集中检索nunit测试属性时出错FS0001或FS0041

时间:2015-01-08 19:35:37

标签: f# nunit

下面的F#脚本因FS0041而失败(无法根据此程序点之前的类型信息确定方法'GetCustomAttributes'的唯一重载。可能需要类型注释)。你是如何解决的?

如果我添加类型注释,例如

let getattr (el : Sometype) = Attribute.CustomAttributes(el, true)

它与FS0001失败('Sometype'类型与'Assembly'类型不兼容。 可能的重载:...省略了长行......)

open System
open System.Reflection

let nunit_tattr = typeof<NUnit.Framework.TestFixtureAttribute>
let getattr el = Attribute.GetCustomAttributes(el, true)
let _ =
    let asm = Assembly.LoadFile("some_asm_that_contains_nunit_tests.dll")
    let ttypes = asm.GetTypes()
    let allattrs = Seq.map getattr ttypes
    printf "%A\n" allattrs

另一方面,在REPL中我得到了更多。

    > let z  = ttypes.[0];;

    val z : Type = Foo.Bar.Cow.Test.AaaTest

    > Attribute.GetCustomAttributes(z, true);;
    val it : Attribute [] =
    [|NUnit.Framework.TestFixtureAttribute
        {Arguments = [||];
         Categories = null;
         Category = null;
         Description = null;
         Ignore = false;
         IgnoreReason = null;
         TypeArgs = [||];
         TypeId = NUnit.Framework.TestFixtureAttribute;}|]

本练习的目的是过滤掉没有NUnit.Framework.TestFixtureAttribute的方法(该代码未显示)。 ttypes中的数组元素是异构的,例如上面所示的索引0 类型为Foo.Bar.Cow.Test.AaaTest,但索引1的类型为Foo.Bar.Cow.Test.BbbTest等。

像这样启动fsharpi

    fsharpi /r:/usr/lib/cli/nunit.framework-2.6/nunit.framework.dll

1 个答案:

答案 0 :(得分:2)

我认为您需要阅读反思以及Type类型实际代表的内容。

为了帮助您入门 - 如果您想获取具有特定属性的类型,请查看以下脚本:

open System
open System.Reflection

/// an attribute and some types to test it on
type ExampleAttribute () = 
   inherit Attribute ()

[<Example>] type A = A
type B = B    
[<Example>] type C = C

/// get the types in an assembly
let types = Assembly.GetExecutingAssembly().GetTypes()

/// filter the types that are marked with ExampleAttribute (gives you A and C)
types 
|> Array.filter (fun typ -> typ.IsDefined(typeof<ExampleAttribute>))

注意typeof运算符 - 它是从静态类型名称(代码中的ExampleAttribute字符串)到类型为Type的对象的方式,它是ExampleAttribute类型的运行时表示形式。