详解c# 协变和逆变

详解C# 协变和逆变

什么是协变和逆变

C#中的协变和逆变都是关于类型转换的扩展,它们开启了更多利用类型层次结构优化代码的可能性。

协变

协变是指派生类对象可以赋值给基类对象的一种类型转换,即如果有A是B的子类,那么IEnumerable<A>可以被隐式转换成IEnumerable<B>。这里的IEnumerable<A>就是协变的例子。在C# 4.0及之后的版本中使用关键字out,来表示协变的类型参数。

示例:

class Person { }
class Student : Person { }

IEnumerable<Student> stuList = new List<Student>();
IEnumerable<Person> pList = stuList; // 协变

上面的例子中,IEnumerable<Student>IEnumerable<Person>的子类,因此可以被隐式地转换。

逆变

逆变是指基类对象可以赋值给派生类对象的一种类型转换,即如果有B是A的基类,那么Action<B>可以被隐式转换成Action<A>。这里的Action<T>就是逆变的例子。在C# 4.0及之后的版本中使用关键字in来表示逆变的类型参数。

示例:

class Person { }
class Student : Person { }

Action<Person> hp = p => Console.WriteLine("Hello " + p.GetType().Name);
Action<Student> hs = hp; // 逆变

上面的例子中,Action<Person>Action<Student>的基类,因此可以被隐式地转换。

在委托中的应用

由于C#中委托是一种类型,因此它们也可以支持协变和逆变。在使用协变和逆变的委托时,需要使用FuncAction泛型委托类型,它们内部指定参数类型和返回值类型可以是协变或逆变的。

示例:

class Person { }
class Student : Person { }

Func<Student, string> getFullName = s => s.GetType().Name;
Func<Person, string> getFullNameForPerson = getFullName; // 协变

Action<Person> hp = p => Console.WriteLine("Hello " + p.GetType().Name);
Action<Student> hs = hp; // 逆变

总结

协变和逆变扩展了C#中类型转换的可能性,可以使代码变得更加灵活,同时也使代码更加简洁易懂。在实际的开发过程中,应该根据具体的场景灵活地使用协变和逆变。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解c# 协变和逆变 - Python技术站

(0)
上一篇 2023年6月7日
下一篇 2023年6月7日

相关文章

  • C#中的虚函数virtual

    当我们在派生类中重写基类的同名函数时,若基类指针或引用指向派生类对象,这时若基类函数被调用,会调用派生类中的函数而不是基类中的函数。但是,如果将基类指针或引用指向派生类对象的实例时,如果使用基类指针或引用来访问这个函数,则只会调用基类中的函数,而不会调用派生类中的函数。为了解决这个问题,C#中引入了虚函数virtual的机制。 虚函数用来实现多态,将基类中的…

    C# 2023年6月7日
    00
  • c#使用xamarin编写拨打电话程序

    很好,下面我来详细讲解一下“c#使用xamarin编写拨打电话程序”的完整攻略。 1. 环境搭建 首先,在开始编写程序前,需要先搭建好环境。我们可以在Visual Studio中使用Xamarin进行开发。在安装 Visual Studio 时选择安装移动开发选项以及Xamarin的组件,或者在已安装的Visual Studio中通过安装工具添加Xamari…

    C# 2023年6月3日
    00
  • C# yield在WCF中的错误使用(二)

    C#yield在WCF中的错误使用(二) 在WCF中使用C#的yield关键字时,需要注意一些问题。在本文中,我们将讨论C#yield在WCF中的错误使用,并提供两个示例。 1. 错误使用C#yield的示例 以下是一个错误使用C#yield的示例: [ServiceContract] public interface IMyService { [Opera…

    C# 2023年5月15日
    00
  • 基于C#的电视台节目表接口调用代码

    要调用电视台节目表接口,需要先了解接口的URL、参数和返回值等信息。以下是基于C#的电视台节目表接口调用代码的完整攻略。 环境准备 在使用C#调用电视台节目表接口前,需要安装.NET Framework和Visual Studio。可以使用以下命令来安装.NET Framework: dotnet-sdk-3.1 实现接口调用 以下是使用C#调用电视台节目表…

    C# 2023年5月15日
    00
  • C#托管堆对象实例包含内容分析

    C#托管堆对象实例包含内容分析 在C#中,对象实例是存储在堆上的,而且它们往往包含各种复杂的属性和字段。在这里,我们将探讨如何分析这些对象实例包含的内容。 调试工具 在C#中,Visual Studio是最常用的调试工具之一。使用Visual Studio,我们可以使用调试器来分析对象实例。以下是一些常用的调试器窗口: Locals窗口:此窗口显示当前方法中…

    C# 2023年6月1日
    00
  • C#.NET字符串比较中忽略符号的方法

    C#.NET字符串比较时,如果需要忽略掉部分或全部符号,我们可以使用以下两种方法: 1. 使用System.Text.RegularExpressions.Regex类 使用System.Text.RegularExpressions.Regex类可以方便地实现忽略符号的字符串比较。代码示例如下: // 声明两个字符串 string str1 = &quot…

    C# 2023年6月1日
    00
  • C#计算程序执行过程花费时间的方法

    一、通过System.Diagnostics.Stopwatch类获取程序执行过程花费时间 引用命名空间System.Diagnostics。 创建Stopwatch实例。 使用Start()方法启动计时器。 执行需要计时的代码逻辑。 使用Stop()方法停止计时器。 使用ElapsedMilliseconds属性获取程序执行的毫秒数。 示例一: using…

    C# 2023年6月1日
    00
  • 使用ASP.NET中关于代码分离的实例分享

    使用ASP.NET进行代码分离是一种将业务逻辑和UI分开的一种重要方式。这种方式能够提高代码的可读性和可维护性。 下面是ASP.NET中关于代码分离的实例分享: 步骤1:创建项目和布局 打开Visual Studio并创建一个ASP.NET MVC项目。 在此项目中,创建一个名为“Controllers”的文件夹。 在“Controllers”文件夹下创建一…

    C# 2023年5月31日
    00
合作推广
合作推广
分享本页
返回顶部