有些算法,比如泛型集合List<T>的Find算法,所查找的对象有可能会是值类型,也有可能是引用类型。在这种算法内部,我们常常会为这些值类型变量或引用类型变量指定默认值。于是,问题来了:值类型变量的默认初始值是0值,而引用类型变量的默认初始值是null值,显然,这会导致下面的代码编译出错:
public T Func<T>()
{
T t=null;
T t=0;
return t;
}
代码"T t=null;"在Visual Studio编译器中会警示:
错误 1 不能将Null转换为类型形参"T",因为它可能是不可以为null值的类型。请考虑改用"default(T)"。
代码"T t=0;"会警示:
错误 1 无法将类型"int"隐式转换为"T"。
C#编译器会阻止这样的代码通过编译。要让编译器接收为一个泛型类型参数指定一个初始值,最妥当的办法就是使用default关键字。所以,在上面的代码应该修改为:
public T Func<T>()
{
T t=default(T);
return t;
}
这样,如果它在运行时碰到的T是一个整型,那么运行时会为其赋值0;如果T在运行时是一个Person这样的引用类型,则会为其赋null值。
查看FCL中的泛型类型,很多地方用到了default关键字。比如List<T>中的Find方法,查看其源码为:
public T Find(Predicate<T>match)
{
if(match==null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
for(int i=0;i<this._size;i++)
{
if(match(this._items[i]))
{
return this._items[i];
}
}
return default(T);
}