我有一个项目,该项目在关闭严格模式和此代码的情况下运行。
Public Overloads Function Save() As Child
Return MyBase.Save()
End Function
打开严格模式后,显示错误:
Option Strict On不允许从“父项”到父项的隐式转换 “孩子”。
我的问题是正在执行父级的保存,还是将子级作为父级的对象转换为子级的类型?
带有所有详细信息的长版:
我试图了解这段代码在VB中清楚地再现它的确切作用,因此可以清楚地将其移植到C#中。
该项目使用CSLA,有一个基础对象,该对象继承自子代的Parent。子级继承父级,而父级继承基。
在子级和父级都有插入。两者都是通过返回对象和函数类型的奇怪区别来调用的吗?
答案 0 :(得分:2)
调用了Child的save函数,但是该函数中的MyBase
关键字调用了父函数。看来Save()
函数的父版本的返回类型为Parent
。就像您拥有以下代码一样:
Public Overloads Function Save() As Child
Dim result As Parent = MyBase.Save()
Return result
End Function
当声明一个函数返回另一种类型时,不允许返回一种类型的对象...除非错误消息告诉您,在这两种类型之间定义了隐式转换,否则将无法返回该类型的对象。 继承不能保证这种转换。
不匹配的回报会导致事情在运行时崩溃。 这种事情正是为什么您应该始终启用Option Strict On 的原因。这将帮助您更好地完成正确的继承类型。
假定Child
继承Parent
时,它将添加自己的字段,属性或方法。至少,这是继承的通常原因。因此,现在您尝试将一个没有任何多余内容的对象返回给不知道丢失的调用者。那是灾难的秘诀。
您可以通过在上面的代码中添加Cast()
来解决此问题,但是由于此处描述的问题,最好重写此代码以使用组合而不是继承。
答案 1 :(得分:2)
如果您尝试拥有Parent
子类Csla.BusinessBase
,然后拥有Child
子类Parent
,则需要像这样实现Parent
:>
Public Class Parent(Of T)
Inherits BusinessBase(Of Parent(Of T))
End Class
Public Class Child
Inherits Parent(Of Child)
Protected Overrides Function SaveAsync(forceUpdate As Boolean, userState As Object, isSync As Boolean) As Task(Of Parent(Of Child))
Return MyBase.SaveAsync(forceUpdate, userState, isSync)
End Function
End Class
这允许通用类型T
从整个继承层次结构向上流动,从而SaveAsync
(或CSLA的较早版本中的Save
)的实现是{{1 }}。