关于泛型和继承(请原谅我不好的标题)
由于我不知道我的问题是如何称呼的,我不能保证最近没有人问过同样的问题,或者根本没有人问过同样的问题。
然而,我确实注意到有很多线程具有相似的标题,但它们似乎与我的问题无关。
我有一个自定义列表类,它实现了泛型。
class MyList<T>
{
public void add(T item) // adds an item to the list
{ /* code */ }
public void add(MyList<T> list) // attaches an existing list to the end of the current one
{ /* code */ }
}
我也有课程:
class Apple : Fruit
现在
class Banana : Fruit
,出现了相关代码:
MyList<Fruit> fruitList = new MyList<Fruit>();
// fill fruitList
fruitList.add(new Apple()); // works, of course
fruitList.add(new Banana()); // works as well, of course
MyList<Apple> appleList = new MyList<Apple>();
// fill appleList
fruitList.add(appleList); // doesn't work. Why?
即使 appleList 是 MyList(Of Apple) 并且 Apple 是 Fruit,当询问 MyList(Of Fruit) 时,VisualStudio 不接受 MyList(Of Apple) 作为参数。
但是,如果我像这样声明列表:
MyList<object> fruitList = new MyList<object>();
那么一切都会恢复正常。我究竟做错了什么?
如果您能得到答案,我们将不胜感激,并且感谢您花时间阅读,即使没有回答。
As I don't know how my problem is called, I cannot guarantee, that nobody has asked the same question recently or at all.
I did notice, however that there are quite a few threads with a similar title, but they don't seem to be relevant to my problem.
I have a custom list class, that implements Generics.
class MyList<T>
{
public void add(T item) // adds an item to the list
{ /* code */ }
public void add(MyList<T> list) // attaches an existing list to the end of the current one
{ /* code */ }
}
I also have the classes:
class Apple : Fruit
and
class Banana : Fruit
Now, comes the relevant code:
MyList<Fruit> fruitList = new MyList<Fruit>();
// fill fruitList
fruitList.add(new Apple()); // works, of course
fruitList.add(new Banana()); // works as well, of course
MyList<Apple> appleList = new MyList<Apple>();
// fill appleList
fruitList.add(appleList); // doesn't work. Why?
Even though appleList is a MyList(Of Apple) and Apple is Fruit, VisualStudio doesn't accept MyList(Of Apple) as argument, when MyList(Of Fruit) is asked.
However, if I were to declare the list like this:
MyList<object> fruitList = new MyList<object>();
Then everything works again. What exactly did I do wrong?
An answer would be much appreciated, and thank you for taking the time to read, even without answering.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在尝试使用协方差。
.Net 仅支持接口上的通用差异,因此这是行不通的。
此外,协方差仅对不可变类型有意义。
如果可以将
MyList
转换为MyList
,那么您就可以将Orange
添加到列表,违反类型安全。相反,您可以使该方法变得通用:
You're trying to use covariance.
.Net only supports generic variance on interfaces, so that won't work.
In addition, covariance only makes sense on immutable types.
Had it been possible to convert a
MyList<Apple>
to aMyList<Fruit>
, you would then be able to add anOrange
to the list, violating type safety.Instead, you can make the method generic:
我认为IMyList接口的设计应该是:
一切按预期进行。为什么?仅仅因为在 .NET 4.0 中 IEnumerable 接口在其类型参数 T 中是协变的,所以定义如下:
IMyList 接口的简单实现(列表装饰器):
I think the design of IMyList interface should be:
Everything works as expected. Why? Just because in .NET 4.0 IEnumerable interface is covariant in it's type parameter T, this is what the definition looks like:
Simple implementation of IMyList interface (List decorator):