这是 F# 编译器错误吗? #3

问题描述 投票:0回答:2

签名文件

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
struct f# warnings
2个回答
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<_>

.

Reflector 还显示代码中缺少

.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()
© www.soinside.com 2019 - 2024. All rights reserved.