【问题标题】:C# inheritance template and casteC#继承模板和种姓
【发布时间】:2019-09-14 14:55:34
【问题描述】:

这是我的第一个问题,请原谅我的无能,

我试图声明一个从同一个类的继承中创建的对象,但它告诉我我不能转换被继承的对象

abstract class BaseEntity{...}

abstract class BaseController<T> where T : Model.BaseEntity{...}

class DummyEntity : BaseEntity {...}

class DummyController : BaseController<DummyEntity> {...}

当我要创建一个对象时,表示不能隐式转换。

BaseController<BaseEntity> a = new DummyController();

【问题讨论】:

  • 什么是CowEntity?我猜这是BaseEntity 的派生类吧?
  • 对不起我的错。
  • 您的 DummyController 继承自 BaseController&lt;CowEntity&gt;,而不是 BaseController&lt;BaseEntity&gt;。即使CowEntity(你没有显示它的定义)继承自BaseEntity(我猜这是你的意图),你仍然会得到错误
  • 你想要的是协方差,它在类中不可用。如果您创建一个像IBaseController&lt;out T&gt; where T : BaseEntity 这样的接口,那么您可以将IBaseController&lt;DummyEntity&gt; 转换为IBaseController&lt;BaseEntity&gt;,但请注意,您只能在T 来自接口中定义的方法或者是只读属性的类型时才能执行此操作, 它不能是方法的参数或可写属性的类型。
  • @juharr 确实。见my answer。我认为这里不值得解释协方差和反方差,因为那里有很多资源可以比我做得更好:)

标签: c# templates inheritance polymorphism


【解决方案1】:

你不能那样做。这和covariance有关。

想象一下BaseController&lt;T&gt; 有一个方法Add(T entity)

现在您创建一个DummyController 的实例。你可以在这个实例上调用Add(CowEntity entity),因为DummyController继承BaseController&lt;CowEntity&gt;所以TCowEntity

现在,如果您能够将其分配给 BaseController&lt;BaseEntity&gt;,您将突然可以调用 Add(BaseEntity entity)(因为 T 现在是 BaseEntity,而不是 CowEntity)。
这意味着您可以将ChickenEntity 的实例(与CowEntity 无关,它只是BaseEntity 的另一个派生类)添加到实际上是BaseController&lt;CowEntity&gt; 的实例的基本控制器。现在突然BaseController&lt;CowEntity&gt; 的一个实例包含ChickenEntity。你看这没有意义。

要解决这个问题,您需要阅读 interfacescovariance (and contravariance)

希望这会有所帮助:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多