从同一函数返回基或其继承的类

本文关键字:继承 函数 返回 | 更新日期: 2023-09-27 18:29:47

这是我在一系列试图理解如何从用于返回基类的函数中返回继承类的问题中的第三个问题。

假设我的代码中定义了以下两个类:

Public Class BaseClass
    Public a As String
    Public b As String
End Class
Public Class DerivedClass
    Inherits BaseClass
    Public d As Integer
End Class

然后,在我的主要程序中,我有以下内容:

Dim MyDerivedList As New List(Of DerivedClass)
Sub Main()
    MyDerivedList = testing()
End Sub
Private Function testing() As IEnumerable(Of BaseClass)
    Dim retval As New List(Of BaseClass)
    Dim toadd1 As New BaseClass
    toadd1.a = "a"
    toadd1.b = "b"
    retval.Add(toadd1)
    Dim toadd2 As New BaseClass
    toadd2.a = "a"
    toadd2.b = "b"
    retval.Add(toadd2)
    Return retval
End Function

根据@Servy在回答我之前的一个问题时所理解的内容(显然是错误的),我假设这将编译并运行。然而,我最终得到以下错误:

Unable to cast object of type 'System.Collections.Generic.List`1[ConsoleApplication1.BaseClass]' to type 'System.Collections.Generic.List`1[ConsoleApplication1.DerivedClass]'

根据@Bjørn RogerKringsjå的评论,我最终将其更改如下:

Private Function testing1(Of TClass As {BaseClass, New})() As IEnumerable(Of TClass)
    Dim retval As New List(Of TClass)
    Dim toadd1 As New TClass
    toadd1.a = "a"
    toadd1.b = "b"
    retval.Add(toadd1)
    Dim toadd2 As New TClass
    toadd2.a = "a"
    toadd2.b = "b"
    retval.Add(toadd2)
    Return retval
End Function
Sub Main()
    MyDerivedList = testing1(Of DerivedClass)()
End Sub

但是,我只是到处乱搞,直到我让它工作。。。根据我之前问题中的评论,我认为我可能做错了。。。做这件事的正确方法是什么?

此外,我知道所有的代码都是用VB编写的,但由于逻辑是一样的,而且我对C#很熟悉,所以这两种语言都很棒!

谢谢!!

从同一函数返回基或其继承的类

在最初的示例中,您犯的错误是试图将基类对象列表分配给派生对象列表。

记住,你总是可以向上转换(好吧,在泛型中,这并不总是正确的,但它适用于List!),所以这个代码很好(以及你应该做的):

public List<DerivedClass> MyMethod()
{
   retList.Add(new DerivedClass());
}
IEnumerable<BaseClass> baseList = MyMethod();

不是相反。很明显,这个代码会导致一个问题(并且是不允许的):

public List<BaseClass> MyMethod()
{
   retList.Add(new OtherDerivedClass());
}
List<DerivedClass> derivedList = MyMethod();

因为现在分配列表中的类型是错误的!

你也可以逃脱(第一个样本):

List<DerivedClass> baseList = MyMethod().OfType<DerivedClass>().ToList();

第二个示例中的泛型代码很好,但当您仍在处理继承时,可能会有点混乱。我会坚持第一种方法,直到你掌握了窍门。