如何将泛型类型指定为泛型方法中的限制

时间:2009-10-15 16:52:17

标签: c# .net generics

我有一个像这样的泛型类:

class MyGenericClass<T> { }

另一方面,我有一个聚合器类,用于获取MyGenericClass和派生类的单例实例,其中每个实例由具体类类型和参数类型标识。也就是说,MyGenericClass<int>MyGenericClass<string>MyDerivedGenericClass<int>不同;每个都有一个单独的实例。

聚合器的主要成员是GetInstanceOf方法,它将返回指定类型的单例实例。问题是我想将类型指定为泛型参数,但我找不到一种方法来创建类型的限制“参数必须是MyGenericClass类型(或派生类型),任何参数类型”< / em>的。简而言之,我想要这样的事情:

T GetInstanceOf<T>() where T : MyGenericClass<> //This does not compile

那么,我该怎么办?有没有办法指定这样的限制?

编辑: GetInstanceOf<T>方法确实返回T,而不是无效。

5 个答案:

答案 0 :(得分:6)

您可能想要创建一个接口,并让您的泛型类实现该接口。 MyGenericClass&LT; INT&GT;和MyGenericClass&lt; string&gt; .NET编译器认为它们是完全不同的类。

这可以让你做这样的事情:

void GetInstanceOf<T>() where T : IMyGenericClass

您还可以使用共享基类:

void GetInstanceOf<T>() where T : MyGenericClassBase

最后,您可以尝试在方法中添加第二个类型参数:

void GetInstanceOf<T, U>() where T: MyGenericClassBase<U>

(我不确定最后一个......我没有编译器方便检查它)

请参阅:http://msdn.microsoft.com/en-us/library/aa479859.aspx#fundamentals_topic12

答案 1 :(得分:4)

interface IMyGenericBase { /* ... */ }

class MyGenericClass<T> : IMyGenericBase { /* ... */ }

class MyDerivedGenericClass<T> : MyGenericClass<T> { /* ... */ }

T GetInstanceOf<T>() where T : IMyGenericBase { /* ... */ }

答案 2 :(得分:2)

我认为你这使得它变得比它需要的复杂得多。退一步解决真正的问题,而不是试图解决一些涉及约束的完全不必要的问题。这似乎非常简单:

MyGenericClass<T> GetInstanceOfMyGenericClass<T>() 
{ 
    return MyGenericClass<T>.GetSingleton(); 
}

你想要一个MyGenericClass<int>,你说GetInstanceOfMyGenericClass<int>()。如果你不需要,为什么要乱用约束呢?

答案 3 :(得分:1)

如果是我,我可能会创建一个接口,让'MyGenericClass'实现该接口,然后在方法签名的'where'中使用该接口。

答案 4 :(得分:1)

我同意这里的大多数帖子 - 提供界面通常是最好的方法。

但是,如果MyGenericClass<T>碰巧是在您的控件之外定义的类,则另一个选项是:

 void GetInstanceOf<T, U>() where T : MyGenericClass<U>

不幸的是,这要求你的调用者也提供MyGenericClass的泛型类型,但如果你不能改变“MyGenericClass”,它将编译并正确运行。