C#2.0中的泛型
using System;
using System.Collections.Generic;
/**/
/*所谓泛型,通过参数化的类型来实现在同一份代码上操作多种数据类型.
* C#泛型赋予了代码更强的类型安全,更好地复用,更高的效率,更清晰的约束.
* C#泛型能力由CLR支持,区别于C++的编译时模板机制,使得泛型能力可以在各个支持CLR的语言之间进行无缝的互造作.
* C#泛型代码在被编译为IL代码和元数据时,采用特殊的占位符来表示泛型类型,并用专有的IL指令实现泛型支持.
* Java的泛型是"擦拭法",是编译时泛型;C#的泛型是真正反省,以"on-demand"的方式,发生于JIT编译时.
*
* 第一轮编译时,编译器只把Stack<T>类型产生为'泛型版'的IL代码和元数据--并不进行泛型类型的实例化,T在中间做占位符
* JIT编译时,JIT将int替代"泛型版"的IL代码和元数据中的T--进行泛型类型的实例化
* CLR为所有类型参数为"引用类型"的泛型类型产生同一份代码; 但如果类型参数为"值类型",CLR将分别产生一份独立的代码.
*
* C#泛型的几个特点:
* 如果实例化泛型类型的参数相同,那么JIT编译器会重复的使用该类型,因此C#的动态泛型能力避免了C++静态模板可能导致的代码膨胀问题.
* C#泛型类型携带丰富的元数据,因此C#的泛型可以应用于强大的反射技术
* C#泛型采用"基类,接口,构造器,值类型/引用类型"的约束方式来实现对类型参数的"显式约束',提高了类型安全的同时,也丧失了C++模板局域"签名"的饮食约束所具有的高灵活性.
* */
namespace testGeneric
{
//类似C++语言中的模板类
class Stack<T>
{
private T[] store;
private int position;
private int capacity;
public Stack(int capacity = 10)
{
this.capacity = capacity;
store = new T[this.capacity];
position = 0;
}
public int GetCapacity()
{
return this.capacity;
}
public int GetPosition()
{
return position;
}
public object GetCurrent()
{
return store[position];
}
public void Push(T x)
{
if (position == capacity)
{
throw new System.IndexOutOfRangeException(string.Format("Stack Position {0} : Stack FULL!", capacity));
}
store[position++] = x;
}
public T Pop()
{
if (position == 0)
{
throw new System.IndexOutOfRangeException(string.Format("Stack Empty!", capacity));
}
return store[--position];//注意此处若是写size--则是错误的!
}
}
public class MyClass
{
public static void Main()
{
Stack<int> stack = new Stack<int>(5);
stack.Push(17);
stack.Push(99);
Console.WriteLine("{0},{1}", stack.Pop(), stack.Pop());
stack.Push(781023);
Console.WriteLine("{0}", stack.Pop());
Console.ReadKey();
}
}
}
using System.Collections.Generic;
/**/
/*所谓泛型,通过参数化的类型来实现在同一份代码上操作多种数据类型.
* C#泛型赋予了代码更强的类型安全,更好地复用,更高的效率,更清晰的约束.
* C#泛型能力由CLR支持,区别于C++的编译时模板机制,使得泛型能力可以在各个支持CLR的语言之间进行无缝的互造作.
* C#泛型代码在被编译为IL代码和元数据时,采用特殊的占位符来表示泛型类型,并用专有的IL指令实现泛型支持.
* Java的泛型是"擦拭法",是编译时泛型;C#的泛型是真正反省,以"on-demand"的方式,发生于JIT编译时.
*
* 第一轮编译时,编译器只把Stack<T>类型产生为'泛型版'的IL代码和元数据--并不进行泛型类型的实例化,T在中间做占位符
* JIT编译时,JIT将int替代"泛型版"的IL代码和元数据中的T--进行泛型类型的实例化
* CLR为所有类型参数为"引用类型"的泛型类型产生同一份代码; 但如果类型参数为"值类型",CLR将分别产生一份独立的代码.
*
* C#泛型的几个特点:
* 如果实例化泛型类型的参数相同,那么JIT编译器会重复的使用该类型,因此C#的动态泛型能力避免了C++静态模板可能导致的代码膨胀问题.
* C#泛型类型携带丰富的元数据,因此C#的泛型可以应用于强大的反射技术
* C#泛型采用"基类,接口,构造器,值类型/引用类型"的约束方式来实现对类型参数的"显式约束',提高了类型安全的同时,也丧失了C++模板局域"签名"的饮食约束所具有的高灵活性.
* */
namespace testGeneric
{
//类似C++语言中的模板类
class Stack<T>
{
private T[] store;
private int position;
private int capacity;
public Stack(int capacity = 10)
{
this.capacity = capacity;
store = new T[this.capacity];
position = 0;
}
public int GetCapacity()
{
return this.capacity;
}
public int GetPosition()
{
return position;
}
public object GetCurrent()
{
return store[position];
}
public void Push(T x)
{
if (position == capacity)
{
throw new System.IndexOutOfRangeException(string.Format("Stack Position {0} : Stack FULL!", capacity));
}
store[position++] = x;
}
public T Pop()
{
if (position == 0)
{
throw new System.IndexOutOfRangeException(string.Format("Stack Empty!", capacity));
}
return store[--position];//注意此处若是写size--则是错误的!
}
}
public class MyClass
{
public static void Main()
{
Stack<int> stack = new Stack<int>(5);
stack.Push(17);
stack.Push(99);
Console.WriteLine("{0},{1}", stack.Pop(), stack.Pop());
stack.Push(781023);
Console.WriteLine("{0}", stack.Pop());
Console.ReadKey();
}
}
}
浙公网安备 33010602011771号