上个示例中使用了方法GetCows()。在讨论这个示例时也提到,可以使用泛型方法得到这个方法的更—般形式。在泛型方法中,返回类型和/或参数类型由泛型类型参数来确定。例如:
public T GetDefault<T>() => default(T);
这个小示例使用前面介绍的default关键字,为类型T返回默认值。对这个方法的调用如下所示:
int myDefaultlnt = GetDefault<int> ();
在调用该方法时提供了类型参数T。
这个T与用于给类提供泛型类型参数的类型差异极大。实际上,可以通过非泛型类来实现泛型方法:
public class Defaulter
{
public T GetDefault<T>() => default(T);
}
但如果类是泛型的,就必须为泛型方法类型使用不同的标识符。下面的代码不会编译:
public class Defaulter<T>
{
public T GetDefault<T>() => default(T);
}
必须重命名方法或类使用的类型T。
泛型方法参数可以釆用与类相同的方式使用约束,在此可以使用任意的类类型参数,例如:
public class Defaulter<Tl>
{
public T2 GetDefault<T2>()
where T2 : T1
{
return default(T2);
}
}
其中,为方法提供的类型T2必须与给类提供的T1相同,或者继承自T1。这是约束泛型方法的常用方式。在前面的Farm<T>类中,可以包含下面的方法(在Chl2Ex04的下载代码中包含它们,但己注释掉)。
public Farm<U> GetSpecies<U>() where U : T
{
Farm<U> speciesFarm = new Farm<U>();
foreach (T animal in animals)
{
if (animal is U)
{
speciesFarm.Animals.Add(animal as U);
}
}
return speciesFarm;
}
这可以替代GetCowsO和相同类型的其他方法。这里使用的泛型类型参数U由T约束,T又由Farm<I>类约束为Animal。因此,如果愿意,可以把T的实例视为Animal的实例。
在Chl2Ex04的客户端代码Program.cs中,使用这个新方法需要进行一处修改:
Farm<Cow> dairyFarm = farm.GetSpecies<Cow>();
也可以编写如下代码:
Farm<Chicken> poultryFarm = farm.GetSpecies<Chicken>();
对于继承自Animal的其他类,都可以使用这种方法。
这里要注意,如果某个方法有泛型类型参数,会改变该方法的签名。也就是说,该方法有几个重载版本,它们仅在泛型类型参数上有区别。例如:
public void ProcessT<T>(T opl){ ... }
public void ProcessT<T, U>(T opl){ ... }
使用哪个方法取决于调用方法时指定的泛型类型参数的个数。
已有 22658 名学员学习以下课程通过考试
最需教育客户端 软件问题一手掌握
去 App Store 免费下载 iOS 客户端
点击加载更多评论>>