Mat*_*hew 50 c# inheritance casting
我想做这样的事情:
List<Child> childList = new List<Child>();
...
List<Parent> parentList = childList;
Run Code Online (Sandbox Code Playgroud)
但是,因为parentList是Child的祖先List而不是直接祖先,所以我无法做到这一点.是否有解决方法(除了单独添加每个元素)?
rec*_*ive 74
使用LINQ:
List<Parent> parentList = childList.Cast<Parent>().ToList();
Run Code Online (Sandbox Code Playgroud)
Eri*_*ert 61
不允许直接进行转换,因为无法使其类型安全.如果你有长颈鹿的名单,并将它投入到动物名单中,那么你可以将老虎放入长颈鹿名单中!编译器不会阻止你,因为当然老虎可能会进入动物列表.编译器可以阻止你的唯一地方是不安全的转换.
在C#4中,我们将支持SAFE接口和使用引用类型参数化的委托类型的协方差和逆变.详情请见此处:
http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx
早在2009年,埃里克(Eric)嘲笑我们,C#4中的情况将会改变。那么,我们今天站在哪里?
我的答案中使用的类可以在底部找到。为了使这更容易理解,我们将使用一个Mammal类为“父”,并Cat和Dog类作为“孩子”。猫和狗都是哺乳动物,但是猫不是狗,狗也不是猫。
这仍然是不合法的,并且不能是:
List<Cat> cats = new List<Cat>();
List<Mammal> mammals = cats;
Run Code Online (Sandbox Code Playgroud)
为什么不?猫是哺乳动物,为什么我们不能将猫列表分配给List<Mammal>?
因为,如果允许我们List<Cat>在List<Mammal>变量中存储对a的引用,则可以编译以下代码以将一只狗添加到猫列表中:
mammals.Add(new Dog());
Run Code Online (Sandbox Code Playgroud)
我们绝对不允许这样!请记住,mammals仅是对的引用cats。Dog不Cat属于Cat对象列表,也没有业务涉及。
使用.NET Framework 4的开始,一些通用接口与声明的协变类型参数out通用修饰符在C#4.关键字介绍在这些接口被IEnumerable<T>这当然是由实施List<T>。
这意味着我们现在可以将a List<Cat>转换为IEnumerable<Mammal>:
IEnumerable<Mammal> mammalsEnumerable = cats;
Run Code Online (Sandbox Code Playgroud)
我们不能向其中添加新内容Dog,mammalsEnumerable因为它IEnumerable<out T>是一个“只读”接口,即它没有任何Add()方法,但是现在我们可以cats在任何IEnumerable<Mammal>可以使用a的地方使用它。例如,我们可以mammalsEnumerable与串联List<Dog>以返回新序列:
void Main()
{
List<Cat> cats = new List<Cat> { new Cat() };
IEnumerable<Mammal> mammalsEnumerable =
AddDogs(cats); // AddDogs() takes an IEnumerable<Mammal>
Console.WriteLine(mammalsEnumerable.Count()); // Output: 3. One cat, two dogs.
}
public IEnumerable<Mammal> AddDogs(IEnumerable<Mammal> parentSequence)
{
List<Dog> dogs = new List<Dog> { new Dog(), new Dog() };
return parentSequence.Concat(dogs);
}
Run Code Online (Sandbox Code Playgroud)
类定义:
public abstract class Mammal { }
public class Cat: Mammal { }
public class Dog : Mammal { }
Run Code Online (Sandbox Code Playgroud)