7

我有一个不优雅的解决方案来满足我的需要,但我正在寻找一个优雅的解决方案来替换它。

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

interface IWebService
{
}

abstract class BaseClient<T>
{
}

class SpecializedClient : BaseClient<IWebService>
{
}

class ClientHelper<T> where T : BaseClient<*>
{
}

inTClientHelper<T>任何扩展的类BaseClient无论传入的模板类型如何。

我发现的不优雅的解决方案是:

class ClientHelper<T, U> where T : BaseClient<U> {}

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

class MyClass<A, B, C, D, E, F, G> where A  : MyBaseClass<B, C, D, E, F, G>

一直到采用单一类型的基类。这仅仅是拥有一个复杂的泛型类继承树的成本,还是有一种更简单的方法来做到这一点,同时保留对模板类型的类型限制?

4

2 回答 2

5

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

所以假设BaseClient不是你定义的那样

abstract class BaseClient<T>
{
   //Something about T here
}

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

另一方面,让我们假设它实际上是您的示例所说的:

abstract class BaseClient<T>
{
   //Nothing about T here
}

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

interface IBaseClient
{
   //Nothing about T here
}

abstract class BaseClient<T> : IBaseClient
{ 
    // Whatever you like here
}

ClientHelper变成:

class ClientHelper<T> where T : IBaseClient
{
}
于 2012-04-04T03:42:28.817 回答
0

一种选择似乎是:

interface IWebService
{
}

interface IClient<out T>
{
}

abstract class BaseClient<T> : IClient<T>
{
}

class SpecializedClient : BaseClient<IWebService>
{
}

class ClientHelper<T> where T : IClient<object>
{
}

但是,只有当您BaseClient只返回T并且从不接受它时,这才有效。

于 2012-04-04T04:32:39.033 回答