开发者

Is this an F# compiler bug? #3

Signature file 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>

Implementation file 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

This compiles fine, but with warning FS0314:

The type d开发者_JAVA技巧efinitions in the signature and implementation are not compatible because the field offset was present in the implementation but not in the signature. Struct types must now reveal their fields in the signature for the type, though the fields may still be labelled 'private' or 'internal'.

When I run the code like that, I've got MethodMissingException:

let foo = FooBarSoftware.Foo<int>() // <==

// System.MethodMissingException:
// Method not found: 'Void FooBarSoftware.Foo~1..ctor()'

Also if I use other ctor and call GetEnumerator() method:

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

Is this an compiler bug, that allows to compile interface without implementation after getting an FS0314 warning?

Microsoft (R) F# 2.0 build 4.0.30319.1


Looks like a bug to me. The following runs fine.

Signature file 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>

Implementation file 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 file test.fs:

module test

let foo = FooBarSoftware.Foo<int>() 
let bar = FooBarSoftware.Foo<int>(1)
let e = foo :> seq<_>

.

Reflector also shows .ctor() missing from your code.

Is this an F# compiler bug? #3


You really don't have GetEnumerator in your class. You should read more about interfaces and inheritance in F#: http://msdn.microsoft.com/en-us/library/dd233207.aspx http://msdn.microsoft.com/en-us/library/dd233225.aspx

If you remove the GetEnumerator line from the .fsi file, this should work:

let foo = FooBarSoftware.Foo<int>(1)
let e = (foo :> IEnumerable<_>).GetEnumerator()
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜