详解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#中dynamic关键字的正确用法(推荐)

    下面是“C#中dynamic关键字的正确用法(推荐)”的详细攻略: 什么是dynamic关键字 C#中的dynamic关键字,是用于在运行时(而非编译时)进行类型检查和绑定,它可以让我们代码更加灵活、简洁、易读。 C#中的dynamic和var关键字的区别在于,var关键字是在编译时进行类型判断并声明变量类型,在编译后变量类型就确定了,而dynamic关键字…

    C# 2023年5月15日
    00
  • asp.net(c#)实现从sqlserver存取二进制图片的代码

    实现从SQL Server存取二进制图片需要经历以下步骤: 在SQL Server中创建表来存储图片数据。通常,您需要为每个图像分配两个列:一个用于存储二进制数据,另一个用于存储图像的MIME类型。例如: CREATE TABLE [dbo].[ImageTable]( [ID] INT PRIMARY KEY IDENTITY(1,1), [ImageDa…

    C# 2023年5月31日
    00
  • 在ASP.NET 2.0中操作数据之五十三:在Data Web控件显示二进制数据

    在ASP.NET 2.0中,我们可以使用Data Web控件来操作和显示数据。在一些情况下,我们需要在Data Web控件中显示二进制数据,例如图片、音频等。本文将带您了解如何在Data Web控件中显示二进制数据,包括图片等。 将二进制数据转换为Base64编码 我们可以将二进制数据转换为Base64编码,以便在Data Web控件中进行显示。Base64…

    C# 2023年6月3日
    00
  • ASP.NET Core MVC通过IActionFilter.OnActionExecuting方法,获取Controller的Action方法参数值

    用过ASP.NET Core MVC中IActionFilter拦截器的开发人员,都知道这是一个非常强大的MVC拦截器。最近才发现IActionFilter的OnActionExecuting方法,甚至可以获取Controller的Action方法参数值。 假如我们在ASP.NET Core MVC项目中有一个HomeController,其中有一个Acti…

    C# 2023年4月22日
    00
  • C# 实现Distinct将对象按条件去重

    下面我来具体讲解“C# 实现Distinct将对象按条件去重”的完整攻略。这里我们假设有一组学生对象数据,每个学生对象包含学生的姓名和年龄两个属性,我们需要按照年龄去重,保留年龄较大的学生对象。攻略如下: 1. 定义学生类对象 首先,我们需要定义一个学生类对象,用于存储学生的姓名和年龄信息。 public class Student { public str…

    C# 2023年6月1日
    00
  • c# 基于Titanium爬取微信公众号历史文章列表

    C# 基于Titanium爬取微信公众号历史文章列表攻略 1. 准备工作 1.1 安装Titanium Titanium是一款爬虫框架,需要使用C#编写,因此在开始之前需要确保您已经安装了Titanium。您可以在Titanium官网下载最新版的Titanium,并根据其安装说明进行安装。 1.2 获取微信公众号的cookie 我们需要使用微信公众号的coo…

    C# 2023年5月31日
    00
  • C# AutoMapper 使用方法总结

    C# AutoMapper 使用方法总结 什么是AutoMapper AutoMapper 是一个能够自动将对象中属性映射到另一个对象的属性的开源库。 例如,你可能有一个 Domain 对象,这个对象拥有很多属性。而在你的应用程序的某些位置,你需要传递该对象到 MVC 模型或表示图形,而这个位置需要该 Domain 对象中仅一部分属性。AutoMapper …

    C# 2023年6月3日
    00
  • C#泛型语法详解

    C#泛型语法详解 1.泛型的概念 C#中的泛型是指一种可以将类型参数化的特性。泛型提供了一种创建可重用、类型安全的代码的方法,可以大大简化代码的编写过程。泛型还可以帮助我们避免在强类型语言中最常见的类型转换问题。 2.泛型类型 泛型类型是具有一般性的类型定义,包含泛型类型参数。定义泛型类型可以使用T或其他名字作为泛型类型参数。 public class My…

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