无法将派生 class 分配给其父通用接口

Cannot assign a derived class to its parent generic interface

我正在尝试分配一个继承自派生 class 的 class,但 C# 编译器不允许。

这是我想要实现的示例设置。

using System;

namespace ConsoleApp
{
    interface IInterfaceA
    {
    }

    interface IInterfaceB
    {

    }

    class TypeA : IInterfaceA
    {

    }

    class TypeB : IInterfaceB
    {

    }


    interface IMapper<in TIn, out TOut>
        where TIn : IInterfaceA
        where TOut :IInterfaceB
    {
        TOut MapAToB(TIn input);
    }

    class AToBMapper : IMapper<TypeA, TypeB>
    {
        public TypeB MapAToB(TypeA input) => throw new NotImplementedException();
    }



    class Program
    {
        static void Main(string[] args)
        {
            IMapper<IInterfaceA, IInterfaceB> test = new AToBMapper();
        }
    }
}

一切正常,直到我到达以下行。

IMapper<IInterfaceA, IInterfaceB> test = new AToBMapper();

在其中,C# 编译器因错误而失败,告诉我

Cannot implicitly convert type 'ConsoleApp.AToBMapper' to 'ConsoleApp.IMapper<ConsoleApp.IInterfaceA, ConsoleApp.IInterfaceB>'. An explicit conversion exists (are you missing a cast?)

但是,我似乎无法理解为什么。 IMapper接口的泛型参数分别标记为协变和逆变,我的AtoBMapper继承自ITypeMapper.

这不应该是可能的吗,因为 TypeA 是一个 IInterfaceATypeB 是一个 IInterfaceB ?

如果您分配给 IMapper(TypeA,TypeB),或者如果您将 AToBMapper 实现为 IMapper(IInterfaceA, IInterfaceB),它工作完美。

您正在做的是在具体 class 实现(TypeA、TypeB)上实现映射器,而不是在这些 classes 的通用接口上。因此,在接口允许的情况下,您的实现可能会使用更具体的定义来进行映射。

使用您的实现,您可以做一些事情,比如定义 TypeC class,实现接口 IInterfaceA。此 class 将填充接口 IInterfaceA 并允许在 IMapper(IInterfaceA, IInterfaceB) 上使用。但是实际的实现需要 TypeA class,而不是 TypeC class.

您的 AToBMapper 需要具有特定类型 TypeA 的输入,但您试图将其转换为 IMapper<IInterfaceA, IInterfaceB>,这将允许具有类型 [=13] 的任何输入=].

这是不可能的,因为其他具体 类 可以实现 IInterfaceA,并且无法转换为 TypeA