购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

建议34:为泛型参数设定约束

“约束”这个词可能会引起歧义,有些人可能认为对泛型参数设定约束是限制参数的使用,实际情况正好相反。没有约束的泛型参数作用很有限,倒是“约束”让泛型参数具有了更多的行为和属性。

查看下面的代码,我们会发现参数t1或参数t2仅仅具有object的属性和行为,所以几乎不能在方法中对它们做任何的操作:


class SalaryComputer

{

public int Compare<T>(T t1,T t2)

{

return 0;

}

}

class Salary

{

public int BaseSalary{get;set;}

public int Bonus{get;set;}

}


但是,在加了约束之后,我们会发现参数t1和t2变成了一个有用的对象。由于为其指定了对应的类型,t1和t2现在就是一个Salary了,在方法的内部,它拥有了属性BaseSalary和Bonus,代码如下所示。


class SalaryComputer

{

public int Compare<T>(T t1,T t2)where T:Salary

{

if(t1.BaseSalary>t2.BaseSalary)

{

return 1;

}

else if(t1.BaseSalary==t2.BaseSalary)

{

return 0;

}

else

{

return-1;

}

}

}


那么可以为泛型参数指定哪些约束呢?如下所示:

1)指定参数是值类型(除Nullable外),可以有如下形式:


public void Method1<T>(T t)where T:struct

{

}


2)指定参数是引用类型,可以有如下形式:


public void Method1<T>(T t)where T:class

{

}

public void Method2<T>(T t)where T:Salary

{

}


注意,object不能用来作为约束。

3)指定参数具有无参数的公共构造方法,可以有如下形式:


public void Method1<T>(T t)where T:new()

{

}


注意,CLR目前只支持无参构造方法约束。

4)指定参数必须是指定的基类,或者派生自指定的基类。

5)指定参数必须是指定的接口,或者实现指定的接口。

6)指定T提供的类型参数必须是为U提供的参数,或者派生自为U提供的参数。如下形式:


class Sample<U>

{

public void Method1<T>(T t)where T:U

{

}

}


7)可以对同一类型的参数应用多个约束,并且约束自身可以是泛型类型。

在编码过程中,应该始终考虑为泛型参数设定约束。正像本建议开始的时候所说,约束使泛型参数成为一个实实在在的“对象”,让它具有了我们想要的行为和属性,而不仅仅是一个object。 +ZpQDHRfAv/03PcgzwwVX532/fQQYxq3zkhXvp8dghA1nPMcJHL9DPQHkkowciUg

点击中间区域
呼出菜单
上一章
目录
下一章
×

打开