泛型中的多态 - 传递继承对象时编译错误(无法隐式转换类型)

时间:2013-07-30 13:59:28

标签: c# inheritance polymorphism

以下代码无法编译:

protected override ITaskScheduleAlgorithm<CollectionTask, ICoordinationExecutionService<CollectionTask>> GetAlgorithm()
{
    return new SimpleTaskScheduleAlgorithm<CollectionTask, WorkerServiceConfiguration>();
}

错误是:

无法隐式转换类型...

无法转换的类型:

WorkerServiceConfiguration→ICoordinationExecutionService

虽然类WorkerServiceConfiguration 继承自 ICoordinationExecutionService:

public class WorkerServiceConfiguration : AbstractServiceConfiguration<CollectionTask>
{
...
}

public abstract class AbstractServiceConfiguration<TTask> : ICoordinationExecutionService<TTask>
{
...
}

知道它为什么会发生以及如何解决它?

2 个答案:

答案 0 :(得分:1)

你应该这样做

protected override ITaskScheduleAlgorithm<CollectionTask, ICoordinationExecutionService<CollectionTask>> GetAlgorithm()
{
    return new SimpleTaskScheduleAlgorithm<CollectionTask, ICoordinationExecutionService<CollectionTask>>();
}

然后您可以使用WorkerServiceConfiguration类型对象

答案 1 :(得分:1)

我认为你有太多的仿制药层,而且让人感到困惑。实际的答案是在底部,但首先是一个解释问题的题外话......

您是正确的,WorkerServiceConfiguration继承自ICoordinationExecutionService。这就是为什么这段代码可行的原因:

protected ICoordinationExecutionService<CollectionTask> Test()
{
    return new WorkerServiceConfiguration();
}

但是,你没有返回ICoordinationService。您正在返回ITaskScheduleAlgorithm。忽略第二个是ICoordinationExecutionService的事实,你关心的只是这个接口声明。事实上,为了理解这个问题,让我们进一步简化它:

public interface ITaskScheduleAlgorithm<TType>
{
}

public class SimpleTaskScheduleAlgorithm<TType> : ITaskScheduleAlgorithm<TType>
{
}

public ITaskScheduleAlgorithm<object> GetAlgorithm()
{
    return new SimpleTaskScheduleAlgorithm<string>();
}

如果您尝试运行此简化示例,则会得到完全相同的错误。你知道这个字符串派生自object,所以你可以期待多态,这应该有用。但是,仅仅因为字符串派生自对象并不意味着SimpleTaskScheduleAlgorithm实现了ITaskScheduleAlgorithm。它完全取决于实现的泛型方法。以List为例 - 尽管string派生自object,但是不能将新对象添加到List中。

为了使这项工作成功,您需要在界面声明中添加'out'关键字。对于我们的简单案例:

公共接口ITaskScheduleAlgorithm { }

这表明界面是协变的(参见covariance and contravariance in generics)。请注意,如果没有接受泛型类型实例作为参数的方法,则只能使接口协变。因此,您问题的最终答案是为您的ITaskScheduleAlgorithm接口添加协变支持:

public interface ITaskScheduleAlgorithm<TType, out TType2>
{
}