2011-02-07 53 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()