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

时间:2014-11-07 21:46:34

标签: c# vb.net visual-studio

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

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

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 in his answer to a previous question of mine理解的内容,我假设这将编译并运行。但是,我最终得到以下错误:

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#很满意,所以语言都很棒!

谢谢!

1 个答案:

答案 0 :(得分:0)

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

请记住,你总是可以向上播放(好吧,在通用中并不总是如此,但它适用于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();

第二个示例中的通用代码很好,但在继续使用继承时可能有点混乱。我坚持使用第一种方法,直到你掌握它为止。