最近在学习.NET 2.0了(说来惭愧呀,万多年前就出VS2005了,现在才想起学.NET 2.0),粗略看了下,2.0版本较1.1版本多了不少新的特性,比如MaterPage,Theme,无刷新Call Server等,页面生命周期也多了不少方法,可以更精确的控制页面的呈现过程,令人激动呀。不过今天要说的不是.NET FrameWork 2.0,而是新版C#中的新特性:泛型
还是先看看下面一段代码吧:
using System.Collections.Generic;
using System.Text;
namespace TestConsole2005
{
public interface ITest
{
void dosth();
}
public class TestClass:ITest
{
public TestClass()
{ }
ITest Members
}
public class TestClass2 : ITest
{
public TestClass2()
{ }
ITest Members
}
public class Test<T,T2> where T:ITest,new() where T2:ITest,new()
{
private T mt;
private T2 mt2;
public Test()
{
mt = new T();
mt2 = new T2();
}
public void foo()
{
mt.dosth();
mt2.dosth();
}
}
class Program
{
static void Main(string[] args)
{
Test<TestClass, TestClass2> v = new Test<TestClass1, TestClass2>();
v.foo();
Console.ReadLine();
}
}
}
泛型为我们解决了什么问题呢?
在没有泛型以前,我们在定义变量时都是将它的类型硬编码,比如:
这样在客户端就没有办法改变mt的类型了,除非使用反射,但反射是在运行时指定类型信息,泛型则不同,泛型是在客户端编码时指定类型信息,比如上面的:
这一句就是在实例化Test类时为T和T2指定详细的类型信息。
把这个与下面的运行结果做个比较(只是把类型互换了)就知道泛型的工作方式了:
为什么要使用泛型,其实反射也一样可以实现这样的功能。原因在于使用泛型可以保证类型的安全,而反射是到运行时才绑定类型信息,这样就很有可能出现类型不匹配的情况,而编译器是无法发现的。
最后说明下:
T和T2声明了Test类中的两个泛型类型,他们可以在客户端实例化该类时被显式指定,where是C#2005才有的用于约束泛型类型的关键字,上面的表达式是指泛型T和T2必须指定为实现了ITest接口的类,并且该类可以被实例化。
泛型还可以代替传统的简单工厂模式,总之,泛型的出现是为了支持客户端指定类型信息,而反射是运行时指定类型信息。