首页 > 后端开发 > C++ > 如何在 C# 中安全地将'List”转换为'List”?

如何在 C# 中安全地将'List”转换为'List”?

Mary-Kate Olsen
发布: 2025-01-09 22:51:46
原创
681 人浏览过

How Can I Safely Cast a `List` to a `List` in C#?

安全地将 C# 中的 List<派生类> 转换为 List<基类>

在 C# 中,处理继承和泛型类型时,您可能会遇到需要将派生类对象的列表转换为基类对象的列表的情况。如果基类包含在派生类中被重写的虚方法,这可能会导致问题。

考虑以下示例:

<code class="language-csharp">class Animal
{
    public virtual void Play(List<Animal> animals) { }
}

class Cat : Animal
{
    public override void Play(List<Animal> animals)
    {
        // Cat 特定的实现
    }
}

class Program
{
    static void Main(string[] args)
    {
        Cat cat = new Cat();
        cat.Play(new List<Cat>()); // 错误:参数 1 无法从“System.Collections.Generic.List<Cat>”转换为“System.Collections.Generic.List<Animal>”
    }
}</code>
登录后复制

编译此代码时,您将遇到错误消息“参数 1:无法从 'System.Collections.Generic.List' 转换为 'System.Collections.Generic.List'”。这是因为,尽管 Cat 类重写了 Play 方法,但方法参数类型 (List) 保持不变。

为了解决这个问题,您需要了解泛型协变的概念。泛型协变允许您安全地扩展派生类重写中参数的类型。在本例中,您希望将参数类型从 List 扩展到 List

C# 4 引入了对泛型协变的支持,借助于 IEnumerable 及其协变安全的接口。通过在 Animal 类中将 Play 方法声明为:

<code class="language-csharp">public virtual void Play(IEnumerable<Animal> animals) { }</code>
登录后复制

然后在 Cat 类中重写它:

<code class="language-csharp">public override void Play(IEnumerable<Animal> animals) { }</code>
登录后复制

您可以使 Play 方法协变安全。这允许您将 List 传递给该方法,然后使用协变将其安全地转换为 IEnumerable。修改后的代码如下所示:

<code class="language-csharp">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>
登录后复制

此代码将成功编译并执行,不会出现错误,允许您在基类方法使用 IEnumerable<基类> 定义且派生类使用 IEnumerable<基类> 重写它时,安全地将 List<派生类> 转换为 List<基类>。

以上是如何在 C# 中安全地将'List”转换为'List”?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板