.NET知识梳理——1.泛型Generic
2021-03-21 13:25
标签:HERE 关键字 st3 tca ret 静态属性 派生 fun type 泛型方法声明时,并未写死类型,在调用的时候再指定类型。 延迟声明:推迟一切可以推迟的。 泛型方法:方法名称后面加上尖括号,里面是类型参数 类型参数实际上就是一个类型T声明,方法就可以用这个类型T了。 如下所示: public static void Show { Console.WriteLine($"This is {typeof(CustomMethod)},paramater={t.GetType().Name},value={t}"); } 泛型方法性能跟普通方法一致,泛型声明方法时,并未写死类型,T是什么类型,只有在调用的时候才知道,一个方法能满足不同类型。 一个类满足不同类型的需求 具体如下: public class BaseModel { public int Id { get; set; } } public class GenericClass where T:BaseModel//为泛型基类约束 { } 一个方法满足不同类型的需求 具体如下: public static void Show { Console.WriteLine($"This is {typeof(CustomMethod)},paramater={t.GetType().Name},value={t}"); } 一个接口满足不同类型的需求 //泛型接口 public interface IGenericInterface { public void SayHi(T t); } 一个委托满足不同类型的需求 public delegate void Do 没有约束,泛型会很局限。主要有5中泛型的约束。如下: Where T:BaseModel 可以把BaseModel当作基类 只有该类型的对象或从该类型派生出的对象,可被用作类型参数。(密封类约束的不行,因为没有意义。) //基类 public class BaseModel { public int Id { get; set; } } //泛型类 public class GenericClass where T:BaseModel//为泛型基类约束 { } 调用: GenericConstraint.Show //引用类型约束 public static T Get { return default(T);//default是关键字,根据类型T返回对应的默认值 } 调用: GenericConstraint.Get //值类型约束 Public static D GetD { return default(D); } 调用: GenericConstraint.GetD //无参数构造函数约束 Public static S GetS where S: new()//无餐构造函数约束 { return new S(); } 调用: GenericConstraint.GetS //接口约束 public static void Show2 { t.Basketball(); } 调用: GenericConstraint.Show2 所谓协变、逆变都是跟泛型有关的(多用在接口)。 修饰返回值 让右边用子类,让泛型用起来更方便(子类转父类) Out修饰,协变后只能是返回结果,不能做参数 IEnumerable //out 协变,只能是返回结果(子类转父类) public interface ICustomerListOut { T Get(); } public class CustomerListOut { public T Get() { return default(T); } } ICustomerListOut Func IEnumerable 修饰传入参数 让右边可以用父类,让泛型用起来更方便(父类转子类) In修饰,逆变后只能当作参数 //in 逆变 只能是输入参数(父类转子类) public interface ICustomerListIn { void Show(T t); } public class CustomerListIn { public void Show(T t) { Console.WriteLine(t.GetType().Name); } } //逆变 ICustomerListIn Action public interface IMyList { void Show(inT t); outT Get(); outT Do(inT t); } public class MyList { public void Show(T t) { Console.WriteLine(t.GetType().Name); } public T1 Get() { Console.WriteLine(typeof(T1).Name); return default(T1); } public T1 Do(T t) { Console.WriteLine(t.GetType().Name); Console.WriteLine(typeof(T1).Name); return default(T1); } } IMyList IMyList IMyList IMyList 泛型缓存,每个类型都会生成一个不同的副本(适合不同类型需要缓存一份数据的场景) public class GenericCache { private static string _TypeTime = ""; static GenericCache() { Console.WriteLine("This is GenericCache 静态构造函数"); _TypeTime = $"{typeof(T).FullName}_{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}"; } public static string GetCache() { return _TypeTime; } } /// /// 字典缓存:静态属性常驻内存 /// public class DictionaryCache { private static Dictionary static DictionaryCache() { Console.WriteLine("This is DictionaryCache 静态构造函数"); _TypeTimeDictionary = new Dictionary } public static string GetCache { Type type = typeof(Type); if (!_TypeTimeDictionary.ContainsKey(type)) _TypeTimeDictionary[type] = $"{typeof(T).FullName}_{DateTime.Now.ToString("yyyy-MM-dd HH mm:ss")}"; return _TypeTimeDictionary[type]; } } .NET知识梳理——1.泛型Generic 标签:HERE 关键字 st3 tca ret 静态属性 派生 fun type 原文地址:https://www.cnblogs.com/alannever/p/12723913.html1. 泛型Generic
1.1 引入泛型:延迟声明
1.2 如何声明和使用泛型
1.3 泛型的好处和原理
1.4 泛型类、泛型方法、泛型接口、泛型委托
1.4.1 泛型类型
1.4.2 泛型方法
1.4.3 泛型接口
1.4.4 泛型委托
1.5 泛型约束
1.5.1 基类约束
1.5.2 引用类型约束
1.5.3 值类型约束
1.5.4 无参数构造函数
()1.5.5 接口约束
1.6 协变、逆变
1.6.1 协变
1.6.2 逆变
1.7 泛型缓存