c# - 模板参数中的 "Covariance"

标签 c#

假设我有这两个类

class BaseClass 
{
    protected HashSet<BaseClass> container;
}


class DerivedClass : BaseClass
{
    DerivedClass() 
    {
        container = new HashSet<DerivedClass>(); 
    }
}                         

然后我收到一个错误:无法转换。

由于每个 DerivedClass(应该)是一个 BaseClass,我不太清楚为什么会抛出这个错误,但确实如此。

目标是让 BaseClass 对 container 执行各种操作,只有特别具体的行为与 DerivedClass 相关 - 其​​中,要求容器的类型为 HashSet<DerivedClass> .

这个目标通常是如何实现的?

最佳答案

每个DevrivedClassBaseClass ,但反之则不然。 HashSet<T>不能协变,因为它允许写操作 ( Add )。所以在你的场景中这是可能的:

class BaseClass 
{
   protected HashSet<BaseClass> container;

   public DoSomething()
   {
       container.Add(new BaseClass());   // not legal if container is really a List<DerivedClass>
   }
}

您可以将容器的类型更改为协变的:

class BaseClass 
{
   protected IEnumerable<BaseClass> container;
}

class DerivedClass : BaseClass
{
   DerivedClass() 
  {
      container = new HashSet<DerivedClass>(); 
  }
}

但是只有派生类可以将项目添加到 container (这可能适用于您的设计)。

您也可以尝试使基类泛化:

class BaseClass<T> where T:BaseClass<T> 
{
   protected HashSet<T> container;
}

class DerivedClass : BaseClass<DerivedClass>
{
   DerivedClass() 
  {
      container = new HashSet<DerivedClass>(); 
  }
}

这看起来有点奇怪,但是一个类包含相同类型的对象列表又看起来很奇怪,所以也许在您的真实场景中它是有意义的。

关于c# - 模板参数中的 "Covariance",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18193498/

相关文章:

c# - Directory.CreateDirectory 因无效字符而失败

c# - 非线性余光层

c# - Request.HttpContext.Connection.ClientCertificate 始终为 null

c# - XDocument如何通过xpath搜索

c# - 图片在 Chrome 上工作正常,但在 IE 上不行

c# - 以 Unity 作为 IoC 的 Rebus Servicebus

c# - Azure Functions 使用带有 Http 触发器的取消 token

c# - msbuild和Visual Studio项目配置问题

c# - Exceptions 对话框中的 User-handled 列发生了什么变化?

c# - Xamarin.iOS 如何在没有导航栏时更改状态栏颜色