【问题标题】:errors FS0001 or FS0041 while attempting to retrieve nunit test attributes from an assembly尝试从程序集中检索 nunit 测试属性时出现错误 FS0001 或 FS0041
【发布时间】:2015-01-09 05:43:00
【问题描述】:

下面的 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

【问题讨论】:

  • 实际的错误信息比错误代码更有用。
  • 好的,添加了更多细节
  • ttypes 不是异构的,它是一个类型数组(例如,Type 类型的元素)。
  • 另外,您要查找测试还是测试夹具?你似乎在你的问题中混淆了他们......
  • TestFixtures,刚刚修复

标签: f# nunit


【解决方案1】:

我认为您需要阅读反射以及 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 类型的运行时表示。

【讨论】:

  • 谢谢,它成功了。你能解释一下为什么管道语法消除了错误 FS0072,换句话说“Array.filter (fun typ -> typ.IsDefined(typeof)) 类型”不起作用
  • @snik197:这是 F# 中类型推断工作方式的结果。通过管道,它在到达过滤器之前就已经知道types 的类型。这是一个有用的技巧,但它为您节省的只是编写注释 - Array.filter (fun (typ: Type) -&gt; ...) types 也可以。
猜你喜欢
  • 1970-01-01
  • 2017-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-18
  • 1970-01-01
  • 1970-01-01
  • 2020-04-10
相关资源
最近更新 更多