如何解释F#型铸造输出?

时间:2013-05-19 02:47:14

标签: casting f#

我遇到了关于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是人物类型。输出应该是“嗨,我是一个人。”

怎么解释呢?

2 个答案:

答案 0 :(得分:2)

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

x2 :?> Student

工作正常,但

x :?> Student

将在运行时崩溃。

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

答案 1 :(得分:2)

正如其他人所注意到的,override语法用于定义虚拟成员 简单地说,调用虚拟方法完全符合您的要求:无论是否有任何 upcasts ,都会根据引用的对象的实际类型找到实际的调用方法至,而不是参考的类型。

This document (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."