本篇文章主要介绍泛型的应用。html
泛型是.NET Framework 2.0 版类库就已经提供的语法,主要用于提升代码的可重用性、类型安全性和效率。安全
泛型的定义架构
下面定义了一个普通类和一个泛型类,咱们能够明确看到泛型类和普通类最大的区别就是多了一个<T>。async
因此,这个<T>就标记了,这个类是泛型类。其中这个T,也能够写成A,B,C,D或其余字符。函数
public class Generic { public String Name; }
public class Generic<T> { public T Name; }
泛型,顾名思义,就是泛指的类型。比如男人,女人,白人,黑人,能够泛称为【人】。spa
但类型只能是一个类型。 那么泛型和类型之间是什么关系呢?htm
其实很简单,泛型在定义的时候,是泛指类型;在使用的时候,就须要被指定,到底使用哪一个类型。对象
即,使用时,就不在是泛指类型,而是特定类型。blog
比如,定义时,定义了一我的。但在使用时,必须明确指定,究竟是黑人仍是白人。继承
泛型的使用
泛型类跟普通类的使用方式同样,都须要实例化对象,再由对象来调用内部的属性或方法。
下面代码实例化了泛型Generic,实例化时,还指定了该泛型Generic的指定类型为String。
因此要给泛型Generic的属性Name赋值,就须要赋值字符串类型的值。
public static void Excute() { Generic<String> gs = new Generic<String>(); gs.Name = "Kiba518"; }
下面代码定义了一个Int类型的泛型Generic。
public static void Excute() { Generic<int> gs = new Generic<int>(); gs.Name = 518; }
泛型的默认值
泛型的默认值,以下面代码所示。须要使用default(T)来赋值。
无论泛型究竟是String,int,bool或者是一个Class类型,均可以被自动赋值。
public static void Excute() { Generic<int> gs = new Generic<int>(); gs.Name = 518; Generic<Task> gsTask = new Generic<Task>(); gsTask.Name = new Task(()=> { Console.WriteLine("Kiba518"); }); } public class Generic<T> { public T Name = default(T); }
泛型的约束
在泛型类中,有个特别的约束可供咱们使用。
当咱们不显示的声明时,这个约束不存在。但当咱们显示的声明的时候,这个约束就会执行。
下面,咱们来看看这个特别的约束。
public static void Excute() { Generic<FanXing> gFanXing = new Generic<FanXing>(); Generic<Base> gFanXingBase = new Generic<Base>(); //Generic<string> gs = new Generic<string>(); 这样定义会报错 } public class Generic<T> where T : Base { public T Name = default(T); } public class Base { public string Name { get; set; } } public class FanXing : Base { public new string Name { get; set; } }
如上面代码所示,【where T : Base】就是这个特别的约束。
当显示声明这个约束的时候,定义会限制泛型的类型。
什么是限制泛型的类型呢?
很简单,泛型T,是泛指某一个类型。咱们在定义泛型类时,还需显示的指定类型,此时咱们显示指定的类型,要受这个限制。
这个限制就是指【where T : Base】。
它的限制是,要求咱们指定的类型T必须是Base,或者该类型继承自Base,如FanXing类。
泛型的函数
在C#中,泛型不只能够用于类,还能够直接用于函数。
具体使用方式以下:
public static void Excute() { GenericFunc gf = new GenericFunc(); gf.FanXingFunc<FanXing>(new FanXing() { Name="Kiba518"}); } public class GenericFunc { public void FanXingFunc<T>(T obj) { Console.WriteLine(obj.GetType()); } }
很简单,调用泛型函数的时候,指定泛型函数的[指定类型]便可。
可是,这里咱们发现一个问题,那就是,在泛型函数里,使用泛型对象的时候,咱们发现对象都是object类型的。
那咱们若是想使用泛型对象里的属性和方法时,要怎么办呢?
也很简单,反射就能够了。
下面咱们添加一个反射函数GetPropertyValue,专门用来获取属性。
public class GenericFunc { public void FanXingFunc<T>(T obj) { var name = GetPropertyValue(obj, "Name"); Console.WriteLine(name); } public object GetPropertyValue(object obj, string name) { object drv1 = obj.GetType().GetProperty(name).GetValue(obj, null); return drv1; } }
输出结果以下:
这样咱们就获得了咱们想要的结果,若是想使用泛型类里的函数,道理也同样,只须要用反射来调用便可。
结语
看到这里,有些同窗可能会以为泛型很复杂,连使用其对象下的属性,都得反射,太繁琐了,还不如不用呢。
有这样想法的同窗,内心想一想就行了,若是对老司机这么说,他确定会心里默默的微笑,而后对你说,你想的没错。
而后,你就没有而后了。
泛型的应用,开篇已经说了,主要用在提升代码的可重用性、类型安全性和效率上。
若是只是定义一个类,调用一个属性,那泛型的存在就是鸡肋。
但事实上,咱们的系统永远只有更复杂,更复杂,更复杂。所以泛型才有了用武之地。
----------------------------------------------------------------------------------------------------
注:此文章为原创,任何形式的转载都请联系做者得到受权并注明出处!
若您以为这篇文章还不错,请点击下方的【推荐】,很是感谢!