在写程序时,若需要处理的数据类型不同,但算法相同时,这时候需要用到泛型。泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
泛型类:定义一个类,这个类中某些字段的类型不确定,这些类型可以在类构造的时候确定下来。
class Program
{
static void Main(string[] args)
{
ClassA<int> classA = new ClassA<int>();
classA.a = 1;
classA.b = 2;
Console.WriteLine("a:{0},b:{1}",classA.a,classA.b);
ClassA<string> classB = new ClassA<string>();
classB.a = "A";
classB.b = "B";
Console.WriteLine("a:{0},b:{1}", classB.a, classB.b);
Console.Read();
}
}
class ClassA<T>
{
public T a { get; set; }
public T b { get; set; }
}
泛型方法就是定义一个方法,这个方法的参数类型可以是不确定的,当调用这个方法时再去确定这个方法参数的类型。
static void Main(string[] args)
{
Add<int>(1, 2);
Add<string>("a", "b");
Console.Read();
}
static void Add<T>(T a,T b)
{
Console.WriteLine(a+"和"+b);
}
C#泛型类在编译时,先生成中间代码IL,通用类型T只是一个占位符。在实例化类时,根据用户指定的数据类型代替T并由即时编译器(JIT)生成本地代码,这个本地代码中已经使用了实际的数据类型,等同于用实际类型写的类,所以不同的封闭类的本地代码是不一样的。按照这个原理,我们可以这样认为:
泛型类的不同的封闭类是分别不同的数据类型。
ClassA和ClassA是两个完全没有任何关系的类,你可以把他看成类A和类B,这个解释对泛型类的静态成员的理解有很大帮助。泛型实例化理论参考网址
泛型方法Add也可以用object类来实现,代码如下:
static void Main(string[] args)
{
Add(1, 2);
Console.Read();
}
static void Add(object a,object b)
{
Console.WriteLine(a+"和"+b);
}
但是由于使用object到int,系统会自动进行拆箱、装箱操作,这将对系统的性能产生影响,若处理引用类型时,必须要进行类型的强制转换,也会产生一定的影响,甚至因为类型强制转化而出现错误。
若给T类型的数据约束struct,则T只能接受struct的子类类型,否则编译错误
class Program
{
static void Main(string[] args)
{
ClassA<int> classA = new ClassA<int>(1, 2);
Console.WriteLine(classA.a+","+classA.b);
// ClassA classB = new ClassA("a","b"); 编译错误!!!
Console.Read();
}
}
class ClassA<T> where T : struct
{
public T a { get; set; }
public T b { get; set; }
public ClassA(T a,T b)
{
this.a = a;
this.b = b;
}
}