如前所述,对于 void 方法,使用上没有太大区别。
如果您查看幕后,您会发现使用泛型方法,.NET 将为您调用它的每种类型编译一个单独的方法。这具有在使用结构调用时避免装箱的效果。
当您使用返回类型时,就会出现很大的差异。
public T Method1<T>(class1 c, T obj) where T: IMyInterface
and
public IMyinterface Method2(class1 c, IMyInterface obj)
使用泛型版本,您可以恢复原始类型,因此可以继续调用原始类型的属性或方法(实例或扩展)。
使用非泛型版本,您只能返回类型的值IMyInterface
,因此您只能调用属于IMyInterface
.
在我的书中,当与扩展方法和流畅风格的 API 一起使用时,这是最有趣的。
public static T Move<T>(this T animal) where T : ICanMove
{
return animal;
}
public static T Fly<T>(this T animal) where T : ICanFly
{
return animal;
}
public static T Pounce<T>(this T animal) where T : ICanPounce
{
return animal;
}
鉴于 Tiger 实现了 ICanMove 和 ICanPounce,而 Eagle 实现了 ICanMove 和 ICanFly,我可以调用适用于原始类型的上述扩展方法。 Intellisense 将显示可用于老鹰的 .Fly() 和 .Move(),以及可用于老虎的 .Pounce() 和 .Move()。
var birdie = new Eagle();
birdie
.Move()
.Fly()
.Move()
.Fly();
var kitty = new Tiger();
kitty
.Move()
.Pounce()
.Move()
.Pounce();
如果您非通用地实现 Move,则结果如下:
public static ICanMove Move<T>(this ICanMove animal)
{
return animal;
}
由于返回了 ICanMove 接口,编译器不知道它最初是 Eagle 或 Tiger,因此您只能使用属于 ICanMove 接口一部分的扩展、方法或属性。