如何获取基类型项的集合变量来保存派生类型项的集合实例? [英] How to get a collection variable of base type items to hold collection instances of derived type items?

查看:70
本文介绍了如何获取基类型项的集合变量来保存派生类型项的集合实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Collection<BaseType> CollectionBaseType;
Collection<DerivedType1> CollectionDerivedType1;
Collection<DerivedType2> CollectionDerivedType2;





当我声明Collection< basetype>类型的集合时并尝试为其分配一个Collection< derivedtype1>的实例。或Collection< derivedtype2>,我收到编译器错误。这意味着在处理这样的集合时我不能从继承中受益。



有没有办法定义一个可以保存Collection< basetype>,Collection< derivedtype1>的变量;或者Collection< derivedtype2>?



我尝试过:





When I declare a collection of the type Collection<basetype> and try to assign to it an instance of Collection<derivedtype1> or Collection<derivedtype2>, I get a compiler error. This means that I cannot benefit of inheritance when dealing with collections like this.

Is there a way to define a variable that can hold Collection<basetype>, Collection<derivedtype1>, or Collection<derivedtype2>?

What I have tried:

Collection<BaseType> CollectionBaseType;
Collection<DerivedType1> CollectionDerivedType1;
Collection<DerivedType2> CollectionDerivedType2;

推荐答案

你可以使用 object ,但我猜,它不是你想要实现的目标。



由于编译器无法知道你期望的类型,因此无法从基本类型转换为派生类型。
You could use object, but I guess, it's not what you want to achieve.

It's not possible to go from a base type to a derived due the circumstance the compiler couldn't know what type you expect. There are (at least) two possible scenarios for
CollectionDerivedType1 = CollectionBaseType;



所有对象都不是 DerivedType1



1.跳过

2.为空



如果你想过滤你可以使用LINQ,如果这是你想实现的。



希望这会有所帮助。


All the objects, which are not DerivedType1

1. get skipped
2. are null

If you want to filter you could use LINQ, if it this you want to achieve.

Hope this will help.


问题是两个列表不是 协变

The problem is that the two lists aren't covariant:
引用:

在面向对象的编程中,方法的协变返回类型是在子类中重写方法时可以用更窄类型替换的类型。一种值得注意的语言是C ++,这是一种相当普遍的范例。 C#不支持返回类型协方差。

In object-oriented programming, a covariant return type of a method is one that can be replaced by a "narrower" type when the method is overridden in a subclass. A notable language in which this is a fairly common paradigm is C++. C# does not support return type covariance.

协变返回类型 - 维基百科 [ ^ ])



基本上是什么意思是如果你构建集合:

(Covariant return type - Wikipedia[^])

What that basically means is that if you construct collections:

class Animal {...}
class Ape : Animal {...}
class Feline : Animal {...}

List<Ape> apes = new List<Ape>();
List<Feline> cats = new List<Feline>();
List<Animal> animals = new List<Animal>();

然后因为Ape是动物,你可以在任一集合中添加一个新物种: br />

Then because an Ape is an Animal, you can add a new species to either collection:

Ape newSpecies = new Ape("Pans Sapiens");
apes.Add(newSpecies);
animals.Add(newSpecies);

但是如果你试图将它添加到Felines:

But if you try to add it to the Felines:

cats.Add(newSpecies);

您将收到编译错误:

You will get a compilation error:

Argument 1: cannot convert from 'GeneralTesting.frmMain.Ape' to 'GeneralTesting.frmMain.Feline'

这就是你所期望的。

但是......如果你能做你想做的事,你可以这样做:

And that is what you would expect.
But ... if you could do what you want, you could do this:

Ape newSpecies = new Ape("Pans Sapiens");
animals = cats;
animals.Add(newSpecies);

你的Feline系列中会有一个Ape - 这意味着你的应用程序会在你尝试使用它时崩溃。



您可以添加所有项目:

And you would have an Ape in your Feline collection - which means your application will crash later on when you try to use it.

You can add all the items:

animals = new List<Animal>();
List<Ape> apes = new List<Ape>();
List<Feline> cats = new List<Feline>();
...
animals.AddRange(apes);
animals.AddRange(cats);



甚至是明确的:


Or even explicitly:

animals = new List<Animal>();
List<Ape> apes = new List<Ape>();
List<Feline> cats = new List<Feline>();
...
animals.AddRange(apes.ConvertAll(x => (Animal)x));
animals.AddRange(cats.ConvertAll(x => (Animal)x));



但是你不能分配不协变的项目。


But you can't assign items which aren't covariant.


这篇关于如何获取基类型项的集合变量来保存派生类型项的集合实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆