签名文件
Foo.fsi
:
namespace FooBarSoftware
open System.Collections.Generic
[<Struct>]
type Foo<'T> =
new: unit -> 'T Foo
new: 'T -> 'T Foo
// doesn't exists in implementation!
member public GetEnumerator: unit -> IEnumerator<'T>
interface IEnumerable<'T>
实施文件
Foo.fs
:
namespace FooBarSoftware
open System.Collections
open System.Collections.Generic
[<Struct>]
type Foo<'T> =
val offset: int
new (x:'T) = { offset = 1 }
interface IEnumerable<'T> with
member this.GetEnumerator() = null :> IEnumerator<'T>
member this.GetEnumerator() = null :> IEnumerator
编译正常,但有警告
FS0314
:
签名和实现中的类型定义不兼容,因为字段偏移量存在于实现中但不存在于签名中。结构类型现在必须在类型的签名中显示其字段,尽管这些字段可能仍被标记为“私有”或“内部”。
当我运行这样的代码时,我得到了
MethodMissingException
:
let foo = FooBarSoftware.Foo<int>() // <==
// System.MethodMissingException:
// Method not found: 'Void FooBarSoftware.Foo~1..ctor()'
另外,如果我使用其他 ctor 并调用
GetEnumerator()
方法:
let foo = FooBarSoftware.Foo<int>(1)
let e = foo.GetEnumerator() // <==
// System.MethodMissingException:
// Method not found: 'System.Collections.Generic.IEnumerator`1<!0>
// FooBarSoftware.Foo`1.GetEnumerator()'.
这是一个编译器错误吗?它允许在收到
FS0314
警告后编译接口而不实现?
Microsoft (R) F# 2.0 build 4.0.30319.1
对我来说看起来像是一个错误。 以下运行良好。
签名文件
Foo.fsi
:
namespace FooBarSoftware
open System.Collections.Generic
//[<Struct>]
type Foo<'T> =
new: unit -> 'T Foo
new: 'T -> 'T Foo
// doesn't exists in implementation!
//member public GetEnumerator: unit -> IEnumerator<'T>
interface IEnumerable<'T>
实施文件
Foo.fs
:
namespace FooBarSoftware
open System.Collections
open System.Collections.Generic
//[<Struct>]
type Foo<'T> =
val offset: int
new () = { offset = 1 }
new (x:'T) = { offset = 1 }
//member this.GetEnumerator() = null :> IEnumerator<'T>
interface IEnumerable<'T> with
member this.GetEnumerator() = null :> IEnumerator<'T>
member this.GetEnumerator() = null :> IEnumerator
测试文件
test.fs
:
module test
let foo = FooBarSoftware.Foo<int>()
let bar = FooBarSoftware.Foo<int>(1)
let e = foo :> seq<_>
.
Reflector 还显示代码中缺少
.ctor()
。
你的类中确实没有 GetEnumerator。您应该阅读有关 F# 中的接口和继承的更多信息: http://msdn.microsoft.com/en-us/library/dd233207.aspx http://msdn.microsoft.com/en-us/library/dd233225.aspx
如果从 .fsi 文件中删除 GetEnumerator 行,这应该可以工作:
let foo = FooBarSoftware.Foo<int>(1)
let e = (foo :> IEnumerable<_>).GetEnumerator()