文章目录
泛型的简介绍
泛型类型参数    

  类型参数命名指南
类型参数的约束
泛型类
泛型接⼝
泛型⽅法
泛型和数组
泛型委托
运⾏时中的泛型
泛型和反射
泛型和特性

C#泛型机制简介

C#泛型能力由CLR在运行时支持。这使得泛型能力可以在各个支持CLR的语言之间进行无缝的互操作。

C#泛型代码在被编译为IL 代码和元数据时,采用特殊的占位符来表示泛型类型,并用专有的IL 指令支持泛型操作。而真正的泛型实例化工作以“on-demand” 的方式,发生在JIT编译时。

总结:

泛型 就是 把具体的数据类型和算法隔离开

1、C#的泛型能力由CLR在运行时支持,它既不同于C++在编译时所支持的静态模板,也不同于Java在编译器层面使用“擦拭法”支持的简单的泛型。

2、C#的泛型支持包括类、结构、接口、委托四种泛型类型,以及方法成员。

3、C#的泛型采用“基类,接口,构造器,值类型/引用类型”的约束方式来实现对类型参数的“显式约束”,它不支持C++模板那样的基于签名的隐式约束。

 类型参数命名指南

 请使用描述性名称命名泛型类型参数,除非单个字母名称完全具有自我说明性且描述性名称不会增加任 何作用



public interface ISessionChannel<TSession> { /*...*/ }
public delegate TOutput Converter<TInput, TOutput>(TInput from);
public class List<T> { /*...*/ }


对具有单个字母类型参数的类型,考虑使用 T 作为类型参数名称。



public int IComparer<T>() { return 0; }
public delegate bool Predicate<T>(T item);
public struct Nullable<T> where T : struct { /*...*/ }


在类型参数描述性名称前添加前缀 "T"。



public interface ISessionChannel<TSession>
{
TSession Session { get; }
}


请考虑在参数名称中指示出类型参数的约束。 例如,约束为 ISession 的参数可命名为 TSession 。  

类型参数的约束

 

在应用 where T : class 约束时,请避免对类型参数使用 == 和 != 运算符,因为这些运算符仅测试引用标识而 不测试值相等性。 即使在用作参数的类型中重载这些运算符也会发生此行为。 下面的代码说明了这一点;即使 String 类重载 == 运算符,输出也为 false。



public static void OpEqualsTest<T>(T s, T t) where T : class
{
System.Console.WriteLine(s == t);
}
private static void TestStringEquality()
{
string s1 = "target";
System.Text.StringBuilder sb = new System.Text.StringBuilder("target");
string s2 = sb.ToString();
OpEqualsTest<string>(s1, s2);
}


 

编译器只知道 T 在编译时是引用类型,并且必须使用对所有引用类型都有效的默认运算符。 如果必须测试值相 等性,建议同时应用 where T : IEquatable 或 where T : IComparable 约束,并在用于构造泛型类的任何类 中实现该接口。

 


编程是个人爱好