【问题标题】:Generic inherited type restriction in C#C# 中的泛型继承类型限制
【发布时间】:2012-04-04 03:32:52
【问题描述】:

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

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

interface IWebService
{
}

abstract class BaseClient<T>
{
}

class SpecializedClient : BaseClient<IWebService>
{
}

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

ClientHelper&lt;T&gt; 中的 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>

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

【问题讨论】:

    标签: c# generics inheritance


    【解决方案1】:

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

    因此,假设 BaseClient 不是您定义的

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

    那么 T 是 BaseClient 的公共接口契约的一部分,因此是 ClientHelper 的公共接口契约的一部分(再次假设 BaseClient&lt;U&gt; 通过 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
    {
    }
    

    【讨论】:

    • 该接口可能适用于其中的一部分,因为我的一些类没有公开公开T,他们只是在内部使用它。我会尽量简化,因为它开始变得笨拙。
    • 这简化了我拥有Class&lt;T&gt; 的所有情况,其中T 从未公开曝光。很简单,但很明显,我看不到。 :-) 它减少了大约一半需要转发的类型。
    • 酷。很高兴它对你有用。如果您可以概括给定T(方法、属性、事件和字段)的所有操作,您也可以消除一些额外的通用参数不依赖于接口的类型。
    【解决方案2】:

    一个选项似乎是:

    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 并且从不接受它时,这才有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-27
      • 2015-09-15
      • 2018-08-01
      相关资源
      最近更新 更多