问题很简单。虽然答案很明显,但我不得不面对一个奇怪的情况,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"
一切都很好。
mmmmmm发生了什么事???
FSharp不应该继承Object
中的每个对象吗?
答案 0 :(得分:14)
你忘记了parens:
type MyType =
val myval: int
override self.ToString() = "Hello MyType"
在原始代码中省略了parens,你试图覆盖属性ToString。
答案 1 :(得分:5)
Desco已经用你的片段解释了问题。
F#就像C#一样,这意味着所有类型都继承自Object
,尽管值类型的行为略微微妙。当您拥有值类型的变量时,它不能直接视为Object
并且需要加框(对于继承自Object
的.NET引用类型)。
这可能会导致类型推断出现一些令人困惑的错误:
let foo x =
match x with
| :? System.Random as rnd -> rnd.Next()
| _ -> 0
当你写这个时,你会收到一条错误信息:
错误FS0008:从“a”到“随机”类型的此运行时强制或类型测试涉及基于此程序点之前的信息的不确定类型。某些类型不允许运行时类型测试。需要进一步的类型注释。
如果从严格意义上的所有内容都继承自Object
,那么F#编译器应该能够将任何类型参数转换为Object
,但这是不允许的。问题是值类型需要装箱,所以你需要写match box x with ...
。
答案 2 :(得分:1)
没有。有些类型不是从对象派生的。例如,接口是不从对象派生的类型。有关详细信息,请参阅http://blogs.msdn.com/b/ericlippert/archive/2009/08/06/not-everything-derives-from-object.aspx。