0

我有一个关于 F# 类型转换的问题。这是代码。

type Person() =
    abstract member SayMe : unit -> unit
    default u.SayMe() = printfn "Hi, I am a person."
type Student() =
    inherit Person()
    override u.SayMe() = printfn "Hi, I am a student."
let x = Person()

let x1 = Student()

let x2 = x1 :> Person

x2.SayMe()|>ignore       
//***Output:"Hi, I am a student."  

x2 是 Person 类型。输出应该是“嗨,我是一个人”。

怎么解释呢?

4

2 回答 2

2

x2 实际上仍然是学生 - 例如

x2 :?> Student

工作正常,但

x :?> Student

运行时会崩溃。

您观察到的行为完全符合 F# 的预期,因为在向下转换后仍会使用被覆盖的函数。

于 2013-05-19T03:08:21.723 回答
2

正如其他人所注意到的,override语法用于定义虚拟成员
简单地说,调用方法完全符合您所看到的:无论任何向上转换,实际调用的方法都将根据引用的对象的实际类型而不是引用的类型找到。

本文档 (MSDN)提供了更多详细信息。

如果您真的不希望该方法是虚拟的,请不要使用override. 这样,派生类中的方法将隐藏其父类的方法。
这是完整的代码:

type Person() =
    member u.SayMe() = printfn "Hi, I am a person."
type Student() =
    inherit Person()
    member u.SayMe() = printfn "Hi, I am a student."

let x = Student()
x.SayMe()             // prints "Hi, I am a student."
(x :> Person).SayMe() // prints "Hi, I am a person."
于 2013-05-19T07:11:27.960 回答