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

C# 泛型中的多态性-传递继承对象时发生编译错误(无法隐式转换类型),c#,inheritance,polymorphism,C#,Inheritance,Polymorphism,以下代码未编译: protected override ITaskScheduleAlgorithm<CollectionTask, ICoordinationExecutionService<CollectionTask>> GetAlgorithm() { return new SimpleTaskScheduleAlgorithm<CollectionTask, WorkerServiceConfiguration>(); } 受保护的覆盖IT

以下代码未编译:

protected override ITaskScheduleAlgorithm<CollectionTask, ICoordinationExecutionService<CollectionTask>> GetAlgorithm()
{
    return new SimpleTaskScheduleAlgorithm<CollectionTask, WorkerServiceConfiguration>();
}
受保护的覆盖ITaskScheduleAlgorithm GetAlgorithm()
{
返回新的SimpleTaskScheduleAlgorithm();
}
错误是:

无法隐式转换类型

无法转换的类型:

WorkerService配置→ ICoordinationExecutionService

当类WorkerServiceConfiguration继承自ICoordinationExecutionService时:

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

public abstract class AbstractServiceConfiguration<TTask> : ICoordinationExecutionService<TTask>
{
...
}
公共类WorkerService配置:AbstractServiceConfiguration
{
...
}
公共抽象类AbstractServiceConfiguration:ICoordinationExecutionService
{
...
}

你知道为什么会发生这种情况以及如何解决吗?

你应该这样做

protected override ITaskScheduleAlgorithm<CollectionTask, ICoordinationExecutionService<CollectionTask>> GetAlgorithm()
{
    return new SimpleTaskScheduleAlgorithm<CollectionTask, ICoordinationExecutionService<CollectionTask>>();
}
受保护的覆盖ITaskScheduleAlgorithm GetAlgorithm()
{
返回新的SimpleTaskScheduleAlgorithm();
}

然后您可以使用
WorkerServiceConfiguration
type对象

我认为您有太多的泛型层,这会让人感到困惑。实际答案在底部,但首先是一个离题的解释问题

您认为WorkerServiceConfiguration继承自ICoordinationExecutionService是正确的。这就是为什么该代码可以工作的原因:

protected ICoordinationExecutionService<CollectionTask> Test()
{
    return new WorkerServiceConfiguration();
}
受保护的ICoordinationExecutionService测试()
{
返回新WorkerServiceConfiguration();
}
但是,您没有返回ICoordinationService。您正在返回一个ITaskScheduleAlgorithm。忽略第二个是ICoordinationExecutionService这一事实,您所关心的只是这个接口声明。事实上,为了理解这个问题,让我们进一步简化它:

public interface ITaskScheduleAlgorithm<TType>
{
}

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

public ITaskScheduleAlgorithm<object> GetAlgorithm()
{
    return new SimpleTaskScheduleAlgorithm<string>();
}
公共接口ITaskSchedule算法
{
}
公共类SimpleTaskScheduleAlgorithm:ITaskScheduleAlgorithm
{
}
公共ITaskScheduleAlgorithm GetAlgorithm()
{
返回新的SimpleTaskScheduleAlgorithm();
}
如果您尝试运行这个简化的示例,您将得到完全相同的错误。您知道字符串是从对象派生的,所以对于多态性,您希望它能够工作。然而,仅仅因为字符串是从对象派生的,并不意味着SimpleTaskScheduleAlgorithm实现了ITaskScheduleAlgorithm。这取决于具体实现了哪些泛型方法。以列表为例,即使字符串来自对象,也不能向列表中添加新对象

为了实现这一点,您需要在接口声明中添加'out'关键字。对于我们的简单案例:

公共接口ITaskSchedule算法 { }

这表示接口是协变的(请参见)。请注意,只有当接口没有接受泛型类型实例作为参数的方法时,才能使其协变。因此,问题的最终答案是向ITaskScheduleAlgorithm接口添加协变支持:

public interface ITaskScheduleAlgorithm<TType, out TType2>
{
}
公共接口ITaskSchedule算法
{
}

在上述示例中,没有类/接口协调执行服务。我不能理解你的建议。很抱歉,我已经编辑了它,我错过了
CoordinationExecutionService
之前的
I
,所以应该有
ICoordinationExecutionService
,我知道这可以工作,但为什么我的代码错了?这就是原始问题。这是C#中的协方差限制,引用和实例应该具有相同的泛型类型。对不起,我真的不知道更多。