那么var cust = (Customer)customer;这句话将编译错误,C#无法进行类型转换,因为对于类型参数T,C#在编译期间根本知道它是什么类型,所以无法进行转换,但是如果对T做个限制,结果会怎么样呢,先看看C#中泛型约束的语法:
  class Shop<T> where T: Customer
  很简单,是增加一个where子句,约束的类型如果有多个可以用逗号隔开,如下:
  class Shop<T> where T: class, ICustomer, new()
  如果类型参数有多个,则写多个where,如下:
  class Shop<T1, T2> where T1:Customer where T2:Superman
  这里要注意的是C#的泛型约束是有很多要求的,约束类型只有6种,如下:
  class:类型实参必须是引用类型;
  struct:类型实参必须是值类型;
  <base class name>:类型实参必须是指定的类或者其派生类;
  <interface name>:类型实参必须是指定的接口类,或其派生类
  new():类型实参必须有一个无参数的公共构造函数;
  U:类型实参T必须是另一个类型实参U或者U的派生类。
  而且where子句内部的约束类型是有顺序要求的,首先class,struct,<base class name>必须只能取其中一个,且只能放在前面,之后是<interface name>,这个可以是多个,而new()必须放在后,向int,string这些 密封类则不能作为约束参数的。
  所以上面的语句如果写成如下,不会有错了,而且VS的IntelliSense会非常智能地弹出customer的成员,如下:

 

class Customer
{
public string Name{get;set;};
public string CreditCardNo{get;set;};
}
class Shop<T>
{
public void Print(T customer)
{
Console.WriteLine(customer.Name);
}
}

  其他关于C++的模板和C#的泛型使用上基本一样,除了C#特有的一些功能,如委托泛型,接口泛型等。
  对了,其实我同事那个问题用object做函数的参数也是可以实现的,但是执行效率比泛型要低。