Файл подписи 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