2011-02-07 35 views
2

签名文件Foo.fsi这是一个F#编译器错误吗? #3

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()' 

另外,如果我使用其他的构造函数,并调用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 
+1

您是否尝试将其报告给[email protected]? – kvb 2011-02-08 04:44:59

回答

3

看起来像一个bug给我。以下运行良好。

签名文件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()缺少您的代码。

Missing Default COnstructor

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()