限制方法中泛型类型的目的是什么?

时间:2015-12-05 22:20:08

标签: c# oop

我很难理解为什么做这样的事情是有益的:(样本是一个类)

static void PrintResults<T>(T result) where T : Sample

将Sample传递给方法会不会更好?

 static void PrintResults (Sample result)

3 个答案:

答案 0 :(得分:10)

我建议避免使用非泛型语法的泛型类型,例如您提供的示例。但是,还有其他有用的案例。

例如,通常指定返回类型:

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)中非常有用,可用于通用相等和比较检查。

答案 1 :(得分:3)

大多数答案都提供了对泛型有用性的解释,这些泛型涉及的接口似乎并不能解决您的实际问题。

事实是,对于您发布的示例,使用通用方法没有任何好处。它实际上是更糟,因为它会导致生成同一函数的多个实现,并且在运行时稍微增加代码大小。

答案 2 :(得分:2)

在空白中你总是可以使用一个接口作为参数来使多种类型工作,所以泛型在这里通常不常用。

只有例外是对泛型的限制。而且我并不是说类似的东西     其中T:IA,IB 因为这可以通过接口完成,并且实现IA和IB。然而,这将在某些时候变得令人厌烦,因为您将需要越来越多的接口。让我们看看“特殊约束”类和新的

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&lt; T&gt;的泛型类。你不想为你需要的每个List实现一个新类。