下面的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
答案 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类型的运行时表示形式。