您的位置:首页 > 编程语言 > C语言/C++

C#中的泛型与C++中的模板

2013-10-22 23:23 288 查看
今天一个同事问我C#中有没有模板函数,他想写一个函数能够处理不同的类型,里面算法一样,如果要重载实现的话,就造成大量重复的代码,而且扩展性不好。我说肯定有啊,你可以上网搜一下,结果他说没搜到,而我对C#根本就不熟,我就和他说你先按照重载的方式先做着,我再查查。

晚上回家之后,拿了本C#的书翻了一下,一下就找到了,就是C#泛型,我猜同事肯定搜的”模板“,所以没搜到。下面记录一下C#的泛型和C++中的模板不同之处:

1,声明方式

C#中的泛型声明方式为,在标识符后面直接加<T>即可,而C++需要使用template关键字,如下:

C#:

class Stack<T>

{

public void Push(T name);

......

};

C++:

template <class T>

class Stack

{

public:

void Push(T name);

};

从上面的两种写法可以看出,显然C#要更简单一些。

上面这是类的泛型化,对于函数的泛型,也类似,如下:

C#:

void Func<T>(T name);

C++:

template <class T>

void Func(T name);

2,泛型约束

C#的泛型比C++模板增加了一个泛型参数约束功能,这在某些场景下非常有用,它可以限制某个泛型参数的使用范围,例如我们可以约束泛型类型Shop<T>的参数只能为Customer类或其子类。如果我们这么写:

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


那么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做函数的参数也是可以实现的,但是执行效率比泛型要低。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C# 泛型 c++ 模板