C# – generics方法与非generics方法

我有点困惑为什么/何时我想要使用generics方法,因为非generics方法可以访问其包含类的generics成员并且无论如何都要传递generics参数。

所以,使用一个可能会忽略这一点的jar头示例(但突出了我为什么要问这个问题),为什么我会这样做:

public class SomeGeneric { public T Swap(ref T a, ref T b) { T tmp = a; a = b; b = tmp; } } 

过度

 public class SomeGeneric { public T Swap(ref T a, ref T b) { T tmp = a; a = b; b = tmp; } } 

这个?

或者,真的,为什么我要使用通用方法呢?

您通常在非generics的类型中使用generics方法。

例如,查看Enumerable类 。 它定义了大多数LINQfunction的通用扩展方法,但它本身并不通用。

您还可能需要generics类型中的generics方法,但前提是generics方法使用不同的generics类型说明符。

这使您可以编写如下内容:

  class Foo where T : IConvertible, IComparable { int CompareTo(U other) where U : IConvertible { // Convert to this T otherConverted = Convert.ChangeType(other, typeof(T)); return this.CompareTo(otherConverted); } } 

(当然,这有点人为,但是对于Foo进行编译和正常工作与double等比较)

如果包含类不通用怎么办? 如果它有不同的generics类型参数怎么办?

第一个例子没有多大意义,因为没有使用类参数。 考虑另一个例子:

 public class SomeGeneric { public K ConvertTo(T a) { return CodeThatConvertsTtoK(a); } } 

及其用法: new SomeGeneric().ConvertToInt("ten");

如果类和方法都是通用的,那么类型参数(“通用参数”)当然必须具有不同的名称。 在你的第一个例子中,不能有两个不同的东西。

如果您的方法是非静态的(如图所示),如果您选择使包含类通用,则在实例化类时必须已指定类型。 像var obj = new SomeGeneric(); 。 所以它应该是逻辑上“属于”类所建模的对象的东西。

如果您的方法是静态的,并且您选择使该类具有通用性,那么您仍然必须以某种方式将类型参数与类一起指定。 如果从类外部调用该方法,它将像SomeGeneric.Swap(ref a, ref b);

使方法通用的优点是,在许多情况下,您可以使用类型推断 ,它允许您省略角度括号类型参数。 您只能使用通用方法执行此操作 。 示例: nonGeneric.Swap(ref a, ref b); 其中Swap方法是通用的。 编译器将查看ab的编译时类型,并确定哪个T适合,而不指定它。

结论:如果T在逻辑上不属于类(如List ),请将其与方法一起使用。

方法级别类型参数的常见方案是扩展方法,因为它们必须在非generics静态类中声明。 但是非通用类型中的每个通用成员都需要它们。

 public static class Extensions { public static void Foo(this A a, B b) { [...] } public static T Bar(this String input) { [...] } public static U FooBar(this V v, W w) { [...] } }