Это ошибка компилятора F #? # 3 - PullRequest
2 голосов
/ 08 февраля 2011

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

Ответы [ 2 ]

3 голосов
/ 08 февраля 2011

Похоже, ошибка для меня.Следующее работает нормально.

Файл подписи 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 голосов
/ 08 февраля 2011

У вас действительно нет 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...