从同一个函数返回一个基类或它的继承类 [英] Returning a base OR its inherited class from the same function
问题描述
这是我试图了解如何从返回基类的函数返回继承类的系列中的第三个问题.
This is my third question in a series of trying to understand how to return an inherited class from a function that is made to return the base class.
假设我在代码中定义了以下 2 个类:
Suppose I have the following 2 classes defined in my code:
Public Class BaseClass
Public a As String
Public b As String
End Class
Public Class DerivedClass
Inherits BaseClass
Public d As Integer
End Class
然后,在我的主要程序中,我有以下内容:
And, then, in my main procedure, I have the following:
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 在他对我之前的一个问题的回答中所理解的,我假设这会编译并运行.但是,我最终收到以下错误:
Based upon what I (obviously incorrectly) understood from @Servy in his answer to a previous question of mine, I was assuming this would compile and run. However, I end up getting the following error:
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å 的评论,我终于能够通过如下更改使其正常工作:
I was finally able to get it to work by changing it as follows based upon a comment by @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
但是,在我开始工作之前,我只是一团糟……根据我之前问题中的评论,我相信我可能做错了……这样做的正确方法是什么?
But, I just messed around until I got it working... Based upon the comments in my earlier question, I believe I might be doing this wrong... What would the right way to do this be?
另外,我知道所有代码都是用 VB 编写的,但由于逻辑是相同的,而且我对 C# 相当熟悉,所以任何一种语言都很棒!
Also, I know all code was written in VB, but since the logic would be the same and I'm fairly comfortable with C#, either language would be great!
谢谢!!
推荐答案
在您的原始示例中,您犯的错误是试图将基类对象列表分配给派生对象列表.
In your original sample, the mistake you made was trying to assign a list of base class objects to a list of derived ones.
记住,你总是可以向上转换(好吧,一般来说,这并不总是正确的,但它适用于 List
!),所以这段代码很好(以及你应该做什么):
Remember, you can always upcast (ok, in a generic thats not always true, but it is for List
!), so this code is fine (and what you should be doing):
public List<DerivedClass> MyMethod()
{
retList.Add(new DerivedClass());
}
IEnumerable<BaseClass> baseList = MyMethod();
但不是相反.显然,此代码会导致问题(并且是不允许的):
But not the other way around. Clearly, this code would cause a problem (and is not allowed):
public List<BaseClass> MyMethod()
{
retList.Add(new OtherDerivedClass());
}
List<DerivedClass> derivedList = MyMethod();
因为现在分配列表中的类型是错误的!
Because now the types in the assigned list are wrong!
您可以也逃脱(从第一个示例中):
You could also have gotten away with (from the first sample):
List<DerivedClass> baseList = MyMethod().OfType<DerivedClass>().ToList();
第二个示例中的通用代码很好,但是当您仍在使用继承时可能会有点混乱.我会坚持使用第一种方法,直到你掌握了它.
The generic code in your second sample is fine, but probably a bit confusing when you are still working with inheritance. I'd stick with the first method until you have the hang of it.
这篇关于从同一个函数返回一个基类或它的继承类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!