F# наследует каждый тип от Object?

Вопрос прост и а. хотя ответ очевиден, мне пришлось столкнуться со странной ситуацией, когда fsharp сказал мне что-то немного странное. Вот история:

Вопрос в следующем: автоматически ли F# заставляет каждый тип наследовать Object учебный класс? Я полагаю, ДА, и я уверен в этом, потому что было бы так много осложнений, если бы это было не так.

Но вот факт. Я писал этот кусок кода:

type MyType =
   val myval: int
   override self.ToString = "Hello MyType"

Хорошо, компилятор fsharp сказал мне, что использование overrid некорректно, потому что он не находит метод, вызываемый ToString переопределить. Я так скомпилировал этот код:

type MyType =
   val myval: int
   member self.ToString = "Hello MyType"

И все работало нормально. мммммм что происходит??? Разве FSharp не должен наследовать каждый объект от Object?

3 ответа

Решение

Вы забыли парней:

type MyType =
   val myval: int
   override self.ToString() = "Hello MyType"

В исходном коде с опущенными символами Паренса вы пытались переопределить свойство ToString.

Desco уже объяснил проблему с вашим фрагментом.

F# ведет себя так же, как C#, что означает, что все типы наследуются от Objectхотя и с немного тонким поведением типов значений. Когда у вас есть переменная типа значения, она не может напрямую рассматриваться как Object и должны быть в штучной упаковке (для ссылочного типа.NET, который наследуется от Object).

Это может вызвать некоторые запутанные ошибки с выводом типа:

let foo x = 
  match x with 
  | :? System.Random as rnd -> rnd.Next()
  | _ -> 0

Когда вы пишете это, вы получаете сообщение об ошибке:

Ошибка FS0008: Это принудительное или типовое испытание во время выполнения от типа 'к случайному типу включает неопределенный тип, основанный на информации, предшествующей этой точке программы. Типовые тесты во время выполнения не разрешены для некоторых типов. Необходимы дополнительные аннотации типов.

Если все унаследовано от Object в строгом смысле, тогда F# компилятор должен быть в состоянии преобразовать любой параметр типа в Object, но это не разрешено. Проблема в том, что типы значений нуждаются в упаковке, поэтому вам нужно написать match box x with ...,

Нет. Есть типы, которые не являются производными от объекта. Интерфейсы, например, являются типами, которые не являются производными от объекта. См. http://blogs.msdn.com/b/ericlippert/archive/2009/08/06/not-everything-derives-from-object.aspx для получения более подробной информации.

Другие вопросы по тегам