非常妙的是,当你实例化两个一样的类型参数string,是共享一份类型规格的,也就是同享一份本地代码,因此上面的代码在线程堆栈和托管堆的大致是这样的:
由于泛型也有元数据的存在,因此可以对其做反射:
Console.WriteLine($"-----------{nameof(lsInt)}---------------"); Console.WriteLine($"{nameof(lsInt)} is generic?:{lsInt.GetType().IsGenericType}"); Console.WriteLine($"Generic type:{lsInt.GetType().GetGenericArguments()[0].Name}"); Console.WriteLine("---------Menthods:"); foreach (var method in lsInt.GetType().GetMethods()) { Console.WriteLine(method.Name); } Console.WriteLine("---------Properties:"); foreach (var property in lsInt.GetType().GetProperties()) { Console.WriteLine($"{property.PropertyType.ToString()}:{property.Name}"); } Console.WriteLine($"\n-----------{nameof(lsStr)}---------------"); Console.WriteLine($"{nameof(lsStr)} is generic?:{lsStr.GetType().IsGenericType}"); Console.WriteLine($"Generic type:{lsStr.GetType().GetGenericArguments()[0].Name}"); Console.WriteLine("---------Menthods:"); foreach (var method in lsStr.GetType().GetMethods()) { Console.WriteLine(method.Name); } Console.WriteLine("---------Properties:"); foreach (var property in lsStr.GetType().GetProperties()) { Console.WriteLine($"{property.PropertyType.ToString()}:{property.Name}"); }输出:
-----------lsInt--------------- lsInt is generic?:True Generic type:Int32 ---------Menthods: get_Item set_Item get_Capacity set_Capacity get_Count Add GetType ToString Equals GetHashCode ---------Properties: System.Int32:Item System.Int32:Capacity System.Int32:Count -----------lsStr--------------- lsStr is generic?:True Generic type:String ---------Menthods: get_Item set_Item get_Capacity set_Capacity get_Count Add GetType ToString Equals GetHashCode ---------Properties: System.String:Item System.Int32:Capacity System.Int32:Count 六.总结泛型编程作为.NET体系中一个很重要的编程思想,主要有以下亮点:
编译期确定类型,避免值类型的拆装箱和不必要的运行时类型检验,同样运行时也能通过is和as进行类型检验
通过约束进行对类型参数实例化的范围
同时在IL层面,实例化相同类型参数的时候共享一份本地代码
由于元数据的存在,也能在运行时进行反射,增强其灵活性
参考Design and Implementation of Generics for the .NET Common Language Runtime
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/
《CLR Via C# 第四版》
《你必须知道的.NET(第二版)》