测试代码如下:namespace CSTest { public class Base { public Base() { } public int Get() { return 0; } } public class Extend : Base { public Extend() { } public int Get() { return 1; } } public static class Program { static void Main() { int Get = Test(new Extend()); Console.WriteLine(Get); }
static int Test<T>(T toGet) where T : Base { return toGet.Get(); } } }输出结果为 0,说明泛型中调用的是基类的函数,也就是说并没有为两种类产生不同的代码。
本质的区别在于:普通的类是在编译时,我的类型是确定的。但我们现实中的某些应用场景下可能需要我的对象来根据实际需要去确定它的类型,如下:class A<T>
{
public T GetCount()
{
//return ToDO
}
}实际上编译时并不能确定 GetCount()方法返回的类型,但是我这样用:
A<int> a=new A<int>();
这样我就在运行时确定了该类的类型
t="int"
A<t> a=new A<t>();
这样才叫运行时,反射才有运行时的功能
我搞错了?!UML里才有泛化的说法,和泛型除了都姓泛以外,没有什么交集吧,
List<T> 并不继承List,我想我没傻吧
运行时中的泛型(C# 编程指南)泛型类
ArrayList.add(string)每次都是要生成一个string类型对象,然后加入到ArrayList中
而List<string>.add(string)加入List<string>时并不知道是string类型对象,是弱类型的,运行时才能确定对象类型
所以List<string>效率比较高
这个和弱类型、运行时扯不上关系的,是装箱拆箱的问题。也没有什么“每次都是要生成一个string类型对象”这种概念,对象要生成早就已经生成了
List<string>.add(int) 编译都过不了,根本不用到运行时
泛型在编译的时候就会产生最终的封闭类型版本,只不过T的实参类型有引用类型与值类型之分罢了
{
public class Base
{
public Base()
{ } public int Get()
{
return 0;
}
} public class Extend : Base
{
public Extend()
{ } public int Get()
{
return 1;
}
} public static class Program
{
static void Main()
{
int Get = Test(new Extend());
Console.WriteLine(Get);
}
static int Test<T>(T toGet) where T : Base
{
return toGet.Get();
}
}
}输出结果为 0,说明泛型中调用的是基类的函数,也就是说并没有为两种类产生不同的代码。
如
FUN(a,b,c,d)而泛型这种“方法”,输入参数是类型,输出的也是类型
TYPE<a,b,c,d>
这个和泛型方法关系不大吧,是因为你的Get相当于new,如果加上override,就是返回1了
我想说明的是泛型和模板的区别,如果用虚函数的话,那么一份代码就可以有不同的行为,在C++中模板是不会管你是不是虚函数的,就算非虚函数,由于一个类型一份代码,其结果也是不同的,所以用虚函数来证明模板与泛型的不同毫无意义。
另外说明一下,为什么C#使用泛型而不是模板,道理很简单,熟悉C++的朋友都知道模板库,比如STL,Boost,MTL,ATL,WTL等等都是源码库,而不是二进制库,原因很简单,因为代码必须在编译时填入类型才会生成。而C#是基于二进制动态连接库的,在这样的系统中实现模板是不可能的。