不同的 return 和声明的函数类型结果,关闭严格模式

Different return and declared function type result, With Strict Mode Off

我有一个项目在关闭严格模式和这段代码的情况下运行。

Public Overloads Function Save() As Child
     Return MyBase.Save()
End Function

打开严格模式后,显示错误:

Option Strict On disallows implicit conversions from 'Parent' to 'Child'.

我的问题是正在执行父对象的保存,或者正在将子对象作为父对象的对象转换为子对象的类型?

包含所有详细信息的长版:

我试图了解这段代码究竟做了什么,以便在 VB 中清楚地重现它,因此它可以清楚地移植到 C#。

项目使用的是CSLA,有一个base object,继承自child的Parent。 Child 继承 Parents,Parents 继承 Base。

子项和父项都有 Insert。 return 对象和函数类型的奇怪差异是否调用了这两个?

调用了 Child 的保存函数,但该函数中的 MyBase 关键字调用了父函数。 Save() 函数的父版本似乎有一个 return 类型的 Parent。所以就好像你有这个代码:

Public Overloads Function Save() As Child
    Dim result As Parent = MyBase.Save()
    Return result
End Function

不允许 return 一种类型的对象,当一个函数被声明为 return 另一种类型时...除非,正如错误消息告诉你的那样,有一个隐含的两种类型之间定义的转换。 继承不保证转换。

不匹配的 returns 会导致运行时崩溃。 这种事情正是您应该始终启用 Option Strict 的原因。它将帮助您更好地获得正确的继承类型。

据推测,当Child继承Parent时,它添加了自己的字段、属性或方法。至少,这是继承的通常原因。所以现在你试图 return 一个没有任何额外东西的对象给一个不知道它丢失的调用者。那是灾难的根源。

您可以通过在上面的代码中添加一个 Cast() 来解决这个问题,但是由于此处描述的问题,最好重新编写它以使用组合而不是继承。

如果您尝试拥有 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)的实现类型为 Child.