详解c#泛型(代码片段)

minotauros minotauros     2023-01-11     804

关键词:

  一、C#中的泛型引入了类型参数的概念,类似于C++中的模板,类型参数可以使类型或方法中的一个或多个类型的指定推迟到实例化或调用时,使用泛型可以更大程度的重用代码、保护类型安全性并提高性能;可以创建自定义的泛型类型(类、结构、接口、委托)和泛型方法;

  1.在泛型类型的定义或泛型方法的声明中,类型参数是类型的占位符,这些占位符指代的类型需要在实例化泛型类型或调用泛型方法时进行指定;

  ※类型参数一般以T命名,如果是多个,使用T、U、V等,如果有指定约束,可以结合约束命名,例如需要继承自MyClass的类型参数命名为TMyClass;任何命名都并不会给类型参数增加额外作用;

  2.泛型是运行时起作用的一套机制,根据运行时类型参数被指定为值类型还是引用类型其使用方式有所不同:

  ※当类型参数被指定为值类型时,会在第一次指定该特定值类型的类型时创建该类型唯一的专用化泛型类型,泛型类型中的类型参数会被替换为相应的值类型;

  ※当类型参数被指定为引用类型时,会在第一次指定任意引用类型时创建一个通用化泛型类型,泛型类型中的类型参数会被替换为该引用类型,并在之后每次指定为引用类型时重用该泛型类型并修改其中类型参数的类型;造成这种差异的原因可能在于所有的引用大小相同;

  二、这篇我们先了解下泛型类,泛型类的定义中可以将类型参数用作成员变量的类型或方法中参数列表、返回值的类型:

class MyClass<T> //声明具有一个类型参数的泛型类,可以有多个类型参数,用,隔开:<T, U>

    public T MyObj; //声明T类型的字段
    private Type myGenericField = typeof(T); //在泛型类内部可以获取类型参数的类型信息
    //do…

//声明泛型类的实例,指定类型参数为int类型
MyClass<int> myObj = new MyClass<int>();

  1.在定义泛型类型时,可以对类型参数的种类添加限制,这些限制称为约束(Constraint),使用约束可以增加类型参数所能进行操作和调用方法的数量;约束使用上下文关键字where指定,位于基类和接口之后,例如:

class MyClass<T> : MyBaseClass where T : MyType //指定基类约束,T需要是指定的类MyType或继承自类MyType,基类约束需要在所有约束之前,基类约束本身也可以是泛型类型,例如MyType<T>

  ※其它特殊的约束:

  where T : IMyInterface //指定接口约束,T需要是指定的接口IMyInterface或实现接口IMyInterface,可以同时指定多个接口约束,接口约束本身也可以是泛型类型,例如IMyInterface<T>
  where T : class //指定类型约束,T需要是类类型
  where T : struct //指定类型约束,T需要是值类型,但不可以是可空类型
  where T : new() //类型参数必须有公共的无参数构造函数,与其他约束一起使用时,new()约束必须最后指定;由于结构的定义中一定包含无参数构造函数,所以struct约束包含new()约束,二者不可同时使用,通常与class约束一起使用:class, new()
  where T : struct where U : class //给多个类型参数指定约束
  where U : T //类型参数作为约束,类型参数U继承自类型参数T

  ※可以对一个类型参数应用多个约束,多个约束使用,隔开:where T : MyType, IMyInterface;

  ※没有约束的类型参数称为未绑定类型参数(Unbounded Type Parameter),这些类型参数的变量在使用时不可以使用==和!=运算符,因为无法保证运行时指定的类型支持这些运算符;

  ※对于使用类型约束class的类型参数,应避免对其变量使用==和!=运算符,因为在泛型中这些运算符仅会根据引用来判断是否相等,即使类型对==和!=运算符进行了重载也不行;如果必须根据值进行判断,应给类型参数加入基类约束IEquatable<T>或IComparable<T>并在类型中实现它们,比较时使用Equals或CompareTo;

  ※从C#7.3开始,可以使用特殊类型System.Delegate、System.MulticastDelegate和System.Enum作为基类约束中的基类,还可以使用非托管类型unmanaged作为类型约束中的类型;

  2.非泛型类(即具体类,Concrete Class)只可以继承自具体类或封闭式构造类(即指定了所有类型参数的泛型类,Closed Constructed Class),不可以继承自开放式构造类(即没有完全指定所有类型参数的泛型类,Open Constructed Class);泛型类可以继承自具体类和封闭式构造类,也可以继承自开放式构造类,继承自开放式构造类时,派生类的类型参数中必须包含基类中未指定类型的类型参数,同时,派生类中这些类型参数的约束必须为基类中对应类型参数约束的超集;可以总结为以下几种情况:

//对于基类为具体类或仅有一个类型参数的情况
class BaseClass  
class BaseGenericClass<T>  
//定义一个泛型类,继承具体类BaseClass
class MyClass<T> : BaseClass  
//定义一个泛型类,继承自指封闭式构造类BaseGenericClass<int>
class MyClass<T> : BaseGenericClass<int>  
//定义一个泛型类,继承自开放式构造类BaseGenericClass<T> 
class MyClass<T> : BaseGenericClass<T>  
//定义一个非泛型类,继承自封闭式构造类BaseGenericClass<int>
class MyClass : BaseGenericClass<int>  
//对于基类有多个类型参数的情况
class MultipleBaseGenericClass<T, U>  
//定义一个泛型类,继承自开放式构造类MultipleBaseGenericClass<T, int>
class MyClass<T> : MultipleBaseGenericClass<T, int>  
//定义一个泛型类,继承自开放式构造类MultipleBaseGenericClass<T, U>
class MyClass<T, U> : MultipleBaseGenericClass<T, U>  
//定义一个非泛型类,继承自封闭式构造类MultipleBaseGenericClass<int, string>
class MyClass : MultipleBaseGenericClass<int, string>  

  ※在继承中,派生类类型的对象可以通过隐式转换赋值给基类类型的变量,这同样适用于泛型类型的对象,例如泛型类List<T>继承自泛型接口IList<T>,那么可以把List<int>类型的对象隐式转换为IList<int>类型的变量:

IList<int> iList = new List<int>();

  3.泛型类为不可变量,泛型类型相同但类型参数指定类型不同的泛型类型即是不同的类型,它们之间不能进行类型转换(即使类型参数指定的类型之间存在类型转换关系),例如不能把List<DerivedClass>类型的对象赋值给一个List<BaseClass>类型的变量;

  4.泛型类最常见的用途是创建泛型集合类,在命名空间System.Collections.Generic中包含系统定义的各种泛型集合类,应尽可能的使用这些泛型集合来代替普通的集合;

 


如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的认可是我写作的最大动力!

作者:Minotauros
出处:https://www.cnblogs.com/minotauros/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。







详解c#泛型(代码片段)

  一、C#中的泛型引入了类型参数的概念,类似于C++中的模板,类型参数可以使类型或方法中的一个或多个类型的指定推迟到实例化或调用时,使用泛型可以更大程度的重用代码、保护类型安全性并提高性能;可以创建自定义... 查看详情

c#泛型详解(代码片段)

这篇文章主要讲解C#中的泛型,泛型在C#中有很重要的地位,尤其是在搭建项目框架的时候。一、什么是泛型泛型是C#2.0推出的新语法,不是语法糖,而是2.0由框架升级提供的功能。我们在编程程序时,经常会遇到功能非常相似的... 查看详情

详解c#的协变和逆变(代码片段)

  一、使用协变(Covariance)和逆变(Contravariance)能够实现数组之间、委托实例和方法之间、泛型委托实例之间、泛型接口的变量和泛型类型的对象之间、泛型接口的变量之间的隐式转换;使用协变将允许使用比原指定类型派... 查看详情

c#之泛型详解

什么是泛型      我们在编写程序时,经常遇到两个模块的功能非常相似,只是一个是处理int数据,另一个是处理string数据,或者其他自定义的数据类型,但我们没有办法,只能分别写多个方法处理每个数据... 查看详情

记录c#泛型(代码片段)

常见的泛型类型泛型类classMyClass<T>//......泛型接口interfaceGenericInterface<T>voidGenericMethod(Tt);泛型方法publicvoidMyGenericMethod<T>()//......泛型数组publicT[]GenericArray;泛型委托publicdelegateTOu 查看详情

c#之泛型详解

什么是泛型      我们在编写程序时,经常遇到两个模块的功能非常相似,只是一个是处理int数据,另一个是处理string数据,或者其他自定义的数据类型,但我们没有办法,只能分别写多个方法处理每个数据... 查看详情

c#泛型generic(代码片段)

泛型:是一种不确定的数据类型    为什么要用泛型,先看一个小例子定义两个普通方法publicclassMethodpublicstaticvoidShowInt(intIntValue)Console.WriteLine($"IntValue=IntValue");publicstaticvoidShowString(stringStrValue 查看详情

详解c#迭代器(代码片段)

  一、迭代器(Iterator)通过持有迭代状态可以获取当前迭代元素并且识别下一个需要迭代的元素,从而可以遍历集合中每一个元素而不用了解集合的具体实现方式;  实现迭代器功能的方法被称为迭代器方法,迭代器方法... 查看详情

c#进阶c#泛型(代码片段)

...18【C#进阶】C#事件19【C#进阶】C#集合类文章目录前言1、泛型的概念2、泛型的使用2.1、类型参数的命名2.2、泛型类2.3、泛型接口2.4、泛型方法2.5、泛型委托3、泛型参数的约束3.1、值类型约束3.2、引用类型约束4、泛型的特性总结... 查看详情

c#基础泛型(代码片段)

1:减少代码的选项可以是用Object类,也可以使用泛型但是Object类进行类型传递不是类型安全的。泛型类使用泛型类型保证了类型安全。泛型类 泛型方法 泛型接口泛型优点:1:性能装箱和拆箱很容易使用,但性能损失比较... 查看详情

c#泛型的静态成员(代码片段)

先来看一下代码publicclassStaticDemo<TType>publicstaticintiValue;publicstaticTTypetValue;publicclassTestStaticMonoBehaviour:MonoBehaviourprivatevoidStart()StaticDemo<int>.iValue=1;StaticDemo&l 查看详情

c#泛型的静态成员(代码片段)

先来看一下代码publicclassStaticDemo<TType>publicstaticintiValue;publicstaticTTypetValue;publicclassTestStaticMonoBehaviour:MonoBehaviourprivatevoidStart()StaticDemo<int>.iValue=1;StaticDemo&l 查看详情

详解java泛型(代码片段)

目录1为什么使用泛型2泛型的语法3.泛型的编译步骤3.1擦除机制3.2不可以实例化泛型类型数组4.了解裸类型5.泛型的上界6.泛型方法7.通配符(?)7.1理解通配符7.2通配符上界7.3通配符下界 8.包装类8.1基本数据类型对应包装类... 查看详情

c#规范整理·泛型委托事件(代码片段)

基于泛型,我们得以将类型参数化,以便更大范围地进行代码复用。同时,它减少了泛型类及泛型方法中的转型,确保了类型安全。委托本身是一种引用类型,它保存的也是托管堆中对象的引用,只不过这个引用比较特殊,它是... 查看详情

java基础:泛型详解(代码片段)

泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。什么是泛型?为什么要使用泛型?泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参... 查看详情

java泛型详解(代码片段)

出处:http://blog.csdn.net/mtawaken/article/details/9813581普通泛型classPoint<T>//此处可以随便写标识符号,T是type的简称privateTvar;//var的类型由T指定,即:由外部指定publicTgetVar()//返回值的类型由外部决定returnvar; 查看详情

java泛型详解-绝对是对泛型方法讲解最详细的,没有之一(代码片段)

...解的用法,才想起详细的记录一下。本文参考java泛型详解、Java中的泛型方法、java泛型详解1.概述泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。什么是泛型?为什么要使用泛型&#x... 查看详情

java基础语法详解java中的泛型(代码片段)

前言:泛型的知识其实在前面Java的泛型和包装类这章介绍过了一些,但那些知识是为后面介绍Java集合框架做的铺垫,而今天这章再配合之前那章,将会完整的介绍Java中的泛型!文章目录1.前章回顾1.1泛型类的... 查看详情