我使用VS 2019中的模板创建了一个F#'Nunit'项目以进行一些测试,它创建的默认灯具代码如下:
namespace Tests
open NUnit.Framework
[<TestClass>]
type TestClass () =
[<SetUp>]
member this.Setup () =
()
[<Test>]
member this.Test1 () =
Assert.Pass()
这是一个看起来很普通的类,除了对类声明的好奇心外。我期望看到[<TestFixture>]
,但我看到的是[<TestClass>]
,它与自动生成的类型同名。我怀疑这是项目模板中的错误,但是奇怪的是,F#会很高兴地对此进行编译,并注意到它可能与其他.Net语言不兼容:
warning FS3242: This type does not inherit Attribute, it will not work correctly with other .NET languages.
对我来说很透明。我的问题是,为什么F#甚至允许这样做? .Net中的反射功能是否甚至可以为F#中的此类属性工作?潜在的用例是什么?
答案 0 :(得分:6)
从历史上看,该检查被忘记添加到编译器中。当发现它时,我建议使其编译错误,但由于向后兼容的原因,最终将其作为警告。有关详细信息,请参见https://github.com/Microsoft/visualfsharp/pull/5192和https://github.com/Microsoft/visualfsharp/pull/5610。
答案 1 :(得分:1)
A,对于F#为何允许这样做的问题,我没有答案。快速实验表明,至少在非常基本的情况下,将普通类用作属性是可行的:
type A(n:int) =
member x.N = n
[<A(10)>]
type B() = class end
(typeof<B>.GetCustomAttributes(true).[1] :?> A).N