继承泛型不能强制转换 [英] Inheriting generic can't up cast

查看:111
本文介绍了继承泛型不能强制转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a problem with inheriting a custom generic. The compiler (Visual Studio for Mac), complaints that the inheriting generic can't be implicitly converted to another, inheriting type. A break down of my code is as follows:

我有一个名为IAnsweredCommon的接口,以及一个从其继承的名为IansweredAndroid的接口

I have an interface called IAnsweredCommon and another interface that inherits from it called IAnsweredAndroid

public interface IAnsweredCommon

public interface IAnsweredAndroid : IAnsweredCommon

我还有另外两个使用这些接口的类.

I have two other classes that use these interfaces.

public abstract class ConstructorCommon<AnsweredType> where AnsweredType : IAnsweredCommon

public class ConstructorAndroid : ConstructorCommon<IAnsweredAndroid>

这有效.通用构造函数具有一个AnsweredType成员变量,使其可以将其视为IAnsweredCommon并对其运行OS不可知代码,同时允许Android构造函数访问相同的成员变量,并且可以将其视为IAnsweredAndroid,从而允许Android构造函数运行特定于Android的代码反对. Android构造函数可以在将OS无关代码传递给通用构造函数的同时处理Android特定的事情.这是我想要的,因为它允许我将其扩展到iOS.

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

This works. The common constructor has a member variable of AnsweredType allowing it to treat it as IAnsweredCommon and run OS agnostic code against it, while allowing the Android constructor access to the same member variable and can treat it as IAnsweredAndroid allowing the Android constructor to run Android specific code against it. The Android constructor can handle Android specific things while passing OS agnostic code to the common constructor. This works and is what I want as it allows me to extend this to iOS.

Now the problem is that I have another layer on top of the constructor. The constructor basically implements the builder design pattern and so it has lots of methods to call in order to construct an answered object. I have director classes that call predetermined constructor methods to create a predetermined answered object.

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

  public class DirectorAndroid : DirectorCommon<ConstructorAndroid>

编译器抱怨无法将ConstructorAndroid隐式转换为ConstructorCommon< \ IAnsweredCommon>.我出于测试目的扩展了ConstructorAndroid,并将其临时更改为:

The compiler complains about being unable to implicitly convert ConstructorAndroid to ConstructorCommon<\IAnsweredCommon>. I've expanded upon ConstructorAndroid for testing purposes and I've temporary changed it to be:

public class DirectorAndroid : DirectorCommon<ConstructorCommon<IAnsweredAndroid>>

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

注意:我已经清理了代码,以使其更易于阅读(删除了名称空间,无关的代码以及诸如此类的东西),因此代码可能不是可运行的",但是无论如何,请指出任何错误,并且我确定它是这是我所缺少的小事,您永远不知道错误是由于清理还是实际错误.

Now, if I change the IAnsweredAndroid interface to IAnsweredCommon, the error goes away (as it should since it exactly matches the constraint). But if I change it to IAnsweredAndroid, I get the error. I'm confused as IAnsweredAndroid IS IAnsweredCommon (inheritance) and therefore, the compiler should be able to upcast IAnsweredAndroid to IAnsweredCommon. After all it's doing this in the constructor classes.

NOTE: I've cleaned up the code to make it easier to read (removed namespaces, irrelevant code and what-not) so the code maybe not be 'runnable', but regardless, please point out any errors and I'm sure it's a minor thing I'm missing and you never know if an error is because of the clean up or if it's an actual error.

推荐答案

这是不可能的,class<A>不能分配给class<B>,即使A是从B派生的,反之亦然.

That is not possible, class<A> is not assignable to class<B>, also if A derives from B or vice versa.

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

It would work, if ConstructorCommon would be an interface, IConstructorCommon, and be defined as:

interface IConstructorCommon<out AnsweredType> where AnsweredType : IAnsweredCommon

输出"使其协变.

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

To replace an abstract base-type with an interface, might be suitable.`

您的错误与约束无关,您发现的只是匹配的方式,导致类型匹配.您可以将ConstructorComman<Android>分配给ConstructorCommon<Android>,但不能分配给ConstructorCommon<Answer>,无论是否存在约束.仅当您要调用特殊方法时才需要约束,只有约束类型才有.

Your error has nothing to do with the constraint, the way you found just matches, cause the type matches. You can assign a ConstructorComman<Android> to ConstructorCommon<Android> but not to ConstructorCommon<Answer> no matter if there is a constraint or not. Constraints you need only if you want to call special methods, that only your constrained-type has.

这篇关于继承泛型不能强制转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆