C#中的通用继承类型限制

For*_*ran 7 c# generics inheritance

我有一个不太优雅的解决方案,我需要的,但我正在寻找一个优雅的解决方案来取代它.

以下代码无法编译,但代表了我想要做的事情:

interface IWebService
{
}

abstract class BaseClient<T>
{
}

class SpecializedClient : BaseClient<IWebService>
{
}

class ClientHelper<T> where T : BaseClient<*>
{
}
Run Code Online (Sandbox Code Playgroud)

其中Tin ClientHelper<T>是任何扩展的类,BaseClient无论传入的模板类型如何.

我找到的不优雅的解决方案是:

class ClientHelper<T, U> where T : BaseClient<U> {}
Run Code Online (Sandbox Code Playgroud)

这变得不优雅的原因是我的项目最终得到了类似于以下的类:

class MyClass<A, B, C, D, E, F, G> where A  : MyBaseClass<B, C, D, E, F, G>
Run Code Online (Sandbox Code Playgroud)

一直到一个类型的基类.这只是具有泛型类的复杂继承树的成本,还是有更简单的方法来保留模板化类型的类型限制?

Chr*_*ain 5

如果BaseClient的公共接口以任何方式公开它的泛型类型参数,那么"不优雅"的解决方案是正确的.

因此,假设BaseClient不是因为你定义它:

abstract class BaseClient<T>
{
   //Something about T here
}
Run Code Online (Sandbox Code Playgroud)

那么T是公共接口契约的BaseClient一部分,因此也是公共接口契约的一部分ClientHelper(同样,假设它BaseClient<U>是通过ClientHelper的接口公开的).

另一方面,让我们假设它实际上就像你的例子所说:

abstract class BaseClient<T>
{
   //Nothing about T here
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,你可以这样做:

interface IBaseClient
{
   //Nothing about T here
}

abstract class BaseClient<T> : IBaseClient
{ 
    // Whatever you like here
}
Run Code Online (Sandbox Code Playgroud)

ClientHelper成为:

class ClientHelper<T> where T : IBaseClient
{
}
Run Code Online (Sandbox Code Playgroud)