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

Кроме того, если я использую другой 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

ответ

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<_> 

.

Отражатель также показывает .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

Если удалить GetEnumerator строки из файла .fsi, это должен работать:

let foo = FooBarSoftware.Foo<int>(1) 
let e = (foo :> IEnumerable<_>).GetEnumerator() 
Смежные вопросы