签名文件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
答案 0 :(得分:3)
对我来说看起来像个错误。以下运行正常。
签名文件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<_>
反射器还会显示代码中缺少.ctor()
。
答案 1 :(得分:2)
你班上真的没有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()