C# 中将 List<派生类> 转换为 List<基类>
在处理继承时,有时需要将派生类对象的列表转换为基类对象的列表。但是,如果处理不当,这可能会导致错误。
使用可写数据进行列表转换的错误
考虑以下代码:
<code class="language-c#">using System; using System.Collections.Generic; class Animal { public virtual void Play(List<Animal> animal) { } } class Cat : Animal { public override void Play(List<Animal> animal) { } } class Program { static void Main(string[] args) { Cat cat = new Cat(); cat.Play(new List<Cat>()); } }</code>
这段代码会由于列表对象类型不匹配而产生编译错误。Animal 期望一个其自身类型的列表 (Animal),而该方法却使用 Cat 对象的列表进行调用。
错误原因
发生此错误的原因是列表是可写的。如果允许转换,则可能导致数据操作问题。例如,可以将狗对象添加到猫的列表中,这将违反类型安全。
泛型协变
在 C# 4 中,引入了名为泛型协变的功能。这允许将派生类的列表转换为基类的列表,前提是这些类型确保类型安全。泛型协变的一个安全类型示例是 IEnumerable<T>
,它表示对象的序列,但无法写入。
实现泛型协变
要实现泛型协变,可以将基类中的方法签名更改为使用 IEnumerable<T>
作为参数类型,如下所示:
<code class="language-c#">class Animal { public virtual void Play(IEnumerable<Animal> animals) { } } class Cat : Animal { public override void Play(IEnumerable<Animal> animals) { } } class Program { static void Main() { Cat cat = new Cat(); cat.Play(new List<Cat>()); } }</code>
在此示例中,Animal 中的 Play 方法采用 IEnumerable<Animal>
作为参数,这允许它接受 Animal 和 Cat 对象的序列。
以上是如何在 C# 中安全地将列表转换为列表?的详细内容。更多信息请关注PHP中文网其他相关文章!