【问题标题】:Inheriting generic can't up cast继承泛型不能向上转换
【发布时间】:2020-01-14 23:33:25
【问题描述】:

我在继承自定义泛型时遇到问题。编译器(Visual Studio for Mac)抱怨继承泛型不能隐式转换为另一个继承类型。我的代码分解如下:

我有一个名为 IAnsweredCommon 的接口和另一个从它继承的名为 IAnsweredAndroid 的接口

public interface IAnsweredCommon

public interface IAnsweredAndroid : IAnsweredCommon

我还有两个使用这些接口的类。

public abstract class ConstructorCommon<AnsweredType> where AnsweredType : IAnsweredCommon

public class ConstructorAndroid : ConstructorCommon<IAnsweredAndroid>

这行得通。公共构造函数有一个 AnsweredType 的成员变量,允许它将其视为 IAnsweredCommon 并针对它运行与操作系统无关的代码,同时允许 Android 构造函数访问相同的成员变量并将其视为 IAnsweredAndroid 允许 Android 构造函数运行 Android 特定代码反对。 Android 构造函数可以处理特定于 Android 的事情,同时将与操作系统无关的代码传递给通用构造函数。这很有效,也是我想要的,因为它允许我将其扩展到 iOS。

现在的问题是我在构造函数之上还有另一层。构造函数基本上实现了构建器设计模式,因此它有很多方法可以调用以构造一个应答对象。我有调用预先确定的构造函数方法来创建预先确定的应答对象的导向器类。

public abstract class DirectorCommon<AnsweredConstructorType>
    where AnsweredConstructorType : ConstructorCommon<IAnsweredCommon>

  public class DirectorAndroid : DirectorCommon<ConstructorAndroid>

编译器抱怨无法将 ConstructorAndroid 隐式转换为 ConstructorCommon。我已经扩展了 ConstructorAndroid 以进行测试,我暂时将其更改为:

public class DirectorAndroid : DirectorCommon<ConstructorCommon<IAnsweredAndroid>>

现在,如果我将 IAnsweredAndroid 接口更改为 IAnsweredCommon,错误就会消失(因为它与约束完全匹配,所以它应该会消失)。但如果我将其更改为 IAnsweredAndroid,我会收到错误消息。我很困惑 IAnsweredAndroid 是 IAnsweredCommon (继承),因此,编译器应该能够将 IAnsweredAndroid 向上转换为 IAnsweredCommon。毕竟它是在构造函数类中执行此操作的。

注意:我已经清理了代码以使其更易于阅读(删除了命名空间、不相关的代码等等),所以代码可能不是“可运行的”,但无论如何,请指出任何错误,我确定它是我遗漏了一件小事,您永远不知道错误是由于清理还是实际错误。

【问题讨论】:

    标签: c# generics inheritance


    【解决方案1】:

    这是不可能的,class&lt;A&gt; 不能分配给 class&lt;B&gt;,如果 A 从 B 派生,反之亦然。

    如果 ConstructorCommon 是一个接口 IConstructorCommon 并被定义为:

    interface IConstructorCommon<out AnsweredType> where AnsweredType : IAnsweredCommon
    

    “out”使它成为协变的。

    用接口替换抽象基类型可能是合适的。`

    您的错误与约束无关,您找到的方式只是匹配,导致类型匹配。无论是否存在约束,您都可以将ConstructorComman&lt;Android&gt; 分配给ConstructorCommon&lt;Android&gt;,但不能分配给ConstructorCommon&lt;Answer&gt;。只有当你想调用特殊方法时才需要约束,只有你的约束类型才有。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-30
      • 2012-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多