我很难理解为什么这样做会有益处:(Sample是一个类)
static void PrintResults<T>(T result) where T : Sample
把Sample直接传递到方法中是否更好呢?
static void PrintResults (Sample result)
我建议在非泛型语法可行的情况下避免使用通用类型,就像你提供的例子一样。然而,还有其他有用的情况。
例如,以泛型方式指定返回类型:
static T Create<T>() where T: Sample, new()
{
return new T();
}
// Calling code
Sample sample = Create<Sample>();
替代
static object Create()
{
return new Sample();
}
// Calling code
Sample sample = (Sample) Create();
您还可以使用模板在类型上设置多个限制条件。例如:
static T Create<T>() where T: IMyInterface, new()
{
return new T();
}
interface IMyInterface {}
class MyClass : IMyInterface { }
// Calling code.
MyClass myClass = Create<MyClass>();
这使得可以通用地创建一个实现特定接口并具有泛型构造函数的新类型。此外:
static void DoSomething<T>(T t) where T: IMyInterface1, IMyInterface2
{
t.MethodOnIMyInterface1();
t.MethodOnIMyInterface2();
}
interface IMyInterface1
{
void MethodOnIMyInterface1();
}
interface IMyInterface2
{
void MethodOnIMyInterface2();
}
class MyClass: IMyInterface1, IMyInterface2
{
// Method implementations omitted for clarity
}
// Calling code
MyClass myclass'
DoSomething(myclass); // Note that the compiler infers the type of T.
您可以在单个参数上要求多个接口,而不需要(1)创建实现所有这些接口的新类型和(2)要求参数为该类型。
正如@dcastro在他/她的答案中指出的那样,泛型类型也可以告诉编译器要求类型相同。例如:
static void DoSomething<T>(T t1, T t2) where T: MyType
{
// ...
}
class MyType {}
class MyType1: MyType {}
class MyType2: MyType {}
// Calling code
MyType1 myType1;
MyType2 myType2;
DoSomething<MyType>(myType1, myType2);
编译器要求t1和t2是相同类型但可以是继承MyType
的任何类型。这在自动化单元测试框架中非常有用,例如NUnit或MSTest,用于通用的等式和比较检查。
DoSomething<MyType>(mytype1, mytype2); DoSomething((MyType)mytype1, mytype2);
... - BrandonISample
有where T : ISample
的话,那么就可以让我们在T
既是struct
又是class
的情况下使用该方法。当我们在方法参数result
上调用接口ISample
的成员时,很酷的一点是,即使T
是值类型(结构体),我们在result
上调用ISample
成员(方法等)时也不会出现装箱。如果结构体具有显式接口实现,我们甚至可以在不装箱结构体的情况下调用它们。 - Jeppe Stig Nielsen大多数回答都提供了关于接口的泛型用途的解释,似乎并未涉及到您实际的问题。
事实上,在您发布的示例中,使用泛型方法没有任何好处。 这实际上是更糟糕的,因为它将导致生成多个相同函数的实现,并在运行时略微增加代码大小。
Sample
必须是引用类型(实际上他告诉我们它是一个“class”)。对于引用类型,不存在“多个实现”。除此之外,在他的特定场景中可能没有太多好处。我们会得到一个额外的类型 T
(这是一个编译时类型,typeof(T)
不一定与result.GetType()
相同)。该方法可以使用该类型,例如 var config = HelperClass<T>.GetConfig();
或类似的东西。 - Jeppe Stig Nielsen在空白处,您可以始终使用接口作为参数,使多种类型起作用,因此泛型在这里通常不是很有用。
唯一的例外是对泛型的限制。我的意思不是像“where T:IA,IB”这样的东西,因为也可以通过实现IA和IB的接口来完成这项工作。然而,随着时间的推移,这将变得繁琐,因为您将需要越来越多的接口。因此,让我们看看“特殊约束”类和new关键字。
public void AddNew(List<T> items) where T : new
{
items.Add(new T());
}
如果方法会改变其参数,那么使用类是有用的,但对于结构体来说则不起作用。
static void IncA<T>(T item) where T: class, IA
{
item.A++;
}
泛型的真正威力在于方法具有泛型返回类型或像List <T>这样的泛型类。您不想为每个需要的List实现一个新类。