优点:
使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。
泛型最常见的用途是创建集合类。
可以创建自己的泛型接口,泛型类,泛型方法,泛型时间,泛型委托。
可以对泛型类进行约束已访问特定数据类型的方法
泛型类型可以应用于强大的反射技术
缺点:
泛型唯一的缺点是...它太容易学又太难理解,以至于绝大多数新手直接把泛型集合和泛型混为一谈,把避免装拆箱当做泛型的唯一目的...反而将泛型的本质都抛弃掉了...
泛型类型参数简介
在定义泛型类型和泛型方法时,常用到泛型类型参数,泛型类型参数是在实例化泛型时指定类型的占位符。泛型类型参数放在“<>”内。
泛型类型参数命名建议:
(1)当泛型类型参数为单个字母时,建议用T表示。
(1)当泛型类型参数用单词定义时,建议在单词前加T。
static void PromptName<T>(T t) {}
static void PromptName<Tuser>(Tuser user){}
泛型类型参数约束
约束 | 说明 |
T:结构 | 类型参数必须是值类型。 可以指定除 Nullable 以外的任何值类型。 |
T:类 | 类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型。 |
T:new() | 类型参数必须具有无参数的公共构造函数。 当与其他约束一起使用时,new() 约束必须最后指定。 |
T:<基类名> | 类型参数必须是指定的基类或派生自指定的基类。 |
T:<接口名称> | 类型参数必须是指定的接口或实现指定的接口。 可以指定多个接口约束。 约束接口也可以是泛型的。 |
T:U | 为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。 |
(1)类型参数约束为结构(struct)
类型参数必须是值类型
static void Main(string[] args)
{
printType < int>(5); //正确的写法
printType<string>("5"); //错误的写法
}
static void printType<T>(T t)where T:struct
{
Console.WriteLine($"类型:{t.GetType().ToString()} 值:{t}");
}
(2)类型参数约束为类(class)
类型参数必须是值类型
static void Main(string[] args)
{
printType < int>(5); //错误的写法
printType<string>("5"); //正确的写法
}
static void printType<T>(T t)where T:class
{
Console.WriteLine($"类型:{t.GetType().ToString()} 值:{t}");
}
(3)类型参数约束为实例化(new())
类型参数必须是可以new的
abstract class A
{
private A()
{
}
}
static void Main(string[] args)
{
printType<A>(new A()); //错误
}
static void printType<T>(T t)where T:new()
{
Console.WriteLine($"类型:{t.GetType().ToString()} 值:{t}");
}
(4)类型参数约束为基类型(基类型)
类型参数必须是指定的基类或派生自指定的基类。
class A
{
}
class B:A
{
}
class C
{
}
static void Main(string[] args)
{
printType<A>(new B()); //正确
printType<A>(new C()); //错误
}
static void printType<T>(T t)where T:A
{
Console.WriteLine($"类型:{t.GetType().ToString()} 值:{t}");
}
(5)类型参数约束为接口类型(接口)
类型参数必须是接口类型
interface IA
{
}
class B:IA
{
}
class C
{
}
static void Main(string[] args)
{
printType<A>(new B()); //正确
printType<A>(new C()); //错误
}
static void printType<T>(T t)where T:A
{
Console.WriteLine($"类型:{t.GetType().ToString()} 值:{t}");
}
(6)类型参数约束为T:U(继承关系,或统一类型)
class A
{
}
class B:A
{
}
class C:B
{
}
static void Main(string[] args)
{
printType<B,A>(new B(),new C());
}
static void printType<T,U>(T t,U,u)where T:U
{
Console.WriteLine($"类型:{t.GetType().ToString()} 值:{t}");
}
获取泛型方法的类型
static void Main(string[] args)
{
printType<B,A>(new B(),new C());
}
static T printType<T,U>(T t,U,u)where T:U //当你不清楚这个方法的返回值是什么,就可以那T代替。
{
Console.WriteLine($"类型:{t.GetType().ToString()} 值:{t}");
return default(T); //当执行到里面的方法时default(T)就会得到它的类型
}