泛型需要引用 System.Collections.Generic 命名空间
泛型的优势
1.代码重用
2.减少装箱拆箱操作,提高性能
3.类型安全
4.代码拓展
泛型方法
1.不使用泛型
1 public void Show(int iValue) 2 { 3 Console.WriteLine("非泛型方法:{0}",iValue.GetType().Name); 4 } 5 public void Show(string sValue) 6 { 7 Console.WriteLine("非泛型方法:{0}", sValue.GetType().Name); 8 } 9 public void Show(DateTime dValue)10 {11 Console.WriteLine("非泛型方法:{0}", dValue.GetType().Name);12 }
或者可以传入Object 值进行Show操作,但会增加装箱拆箱操作,导致性能损失
public void Show(object oValue) { Console.WriteLine("非泛型方法:{0}", oValue.GetType().Name); }
2.使用泛型
public void Show(T t) { Console.WriteLine("泛型方法:{0}", t.GetType().Name); }
泛型延迟声明,在调用时在声明,可以很好的提高性能,减少装箱拆箱,调用如下
Show (1); Show("Test"); Show (DateTime.Now);
泛型类,接口,委托
泛型类的创建
public class MyGeneric{ public void GenericClassShow() { Console.WriteLine(typeof(T).Name); } }
泛型接口的创建
public interface IMyGeneric{ void Show(T t); }
泛型委托的创建
public delegate void Show();
泛型约束
约束 | 说明 |
where T:struct | 结构约束,类型T必须是值类型 |
where T:class | 类型T必须是引用类型 |
where T:IFoo | 类型T必须实现IFoo接口 |
where T:Foo | 类型T必须派生自基类Foo |
where T:new() | 构造函数约束,类型T必须有一个默认构造函数 |
where T1:T2 | 类型T1派生自类型T2 |
public class MyGenericwhere T:class,new() { }
协变与逆变
只作用于泛型接口与泛型委托
先定义一个IPeople接口,People类以及基类Women 和子类Girl
public interface IPeople{ public int Id { get; set; } } public class People :IPeople { } public class Women { } public class Girl:Women { }
当 IPeople<Women> women = new People<Girl>();实例化一个women类的集合时就会报错,需要加入out关键字,表示返回类型只能是T
public interface IPeople{ public int Id { get; set; } }
逆变同理in关键字表示传入的参数只能是T类型,这样就可以通过父类创建子类
public class MyGenericwhere T:class,new() { // IPeople women = new People (); IPeople girl = new People (); } public interface IPeople { public int Id { get; set; } }