如何添加通用约束?

时间:2014-11-18 10:59:14

标签: c# generics constraints

我在C#中遇到以下情况:

class MyGenericClass<T>
{
    public void do()
    {
    }
}

class SpecificFooImpl : MyGenericClass<Foo>
{
     public void otherStuff()
     {
     }
}

现在我想编写一个只返回MyGenericClass或特定实现的泛型方法。我会写一些类似的东西:

var v1 = GetMyClass<MyGenericClass<Foo>>();
var v2 = GetMyClass<MyGenericClass<Bar>>();
var v3 = GetMyClass<SpecificFooImpl>();

我可以使用以下签名,但它对类型没有限制:

public T GetMyClass<T>();
//I don't want to write
//var v4 = GetMyClass<AnyOtherTypesWhichNotExtendMyGenericClass>();

有没有优雅的模式来解决这个问题?

2 个答案:

答案 0 :(得分:2)

在定义后添加where:子句,然后您可以定义应该遵守的内容 我说它必须是一个类,但你可以添加一个基类或接口作为约束。

class MyGenericClass<T> where T : class, IYourCommonInterface
{
    public void do()
    {
    }
}

<强>参考
有关约束,请参阅MSDN:http://msdn.microsoft.com/en-us/library/d5x73970.aspx

答案 1 :(得分:2)

这有点棘手,因为你不能打开类型约束 - 它必须是具体的。

所以你想做的是:

public T GetMyClass<T>() where T: MyGenericClass<>

然而,您最接近的是包含使MyGenericClass具体的第二种通用​​类型:

public T GetMyClass<T,T2>() where T: MyGenericClass<T2>

然而,这使得调用者需要对实现了解太多,尤其是在您使用SpecificFooImpl的情况下。

相反,请考虑使用接口删除内部泛型类型:

interface MyInterface
{
    void Stuff();
}

class MyGenericClass<T> : MyInterface
{
    public void Stuff()
    {
    }
}

然后你可以:

public T GetMyClass<T>() where T : MyInterface