我遇到了关于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是人物类型。输出应该是“嗨,我是一个人。”
怎么解释呢?
答案 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."