猿问

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

我试图分配一个继承自派生类的类,但 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分别标记为协变和逆变,myAtoBMapper继承自ITypeMapper.


这不应该是可能的吗,因为这TypeA是一个IInterfaceA并且TypeB是一个IInterfaceB ?


拉莫斯之舞
浏览 127回答 2
2回答

牧羊人nacy

如果您要分配给 IMapper(TypeA,TypeB),或者如果您将 AToBMapper 实现为 IMapper(IInterfaceA, IInterfaceB),那么它工作得非常完美。您正在做的是在具体的类实现(TypeA、TypeB)上实现映射器,而不是在这些类的通用接口上实现。因此,您的实现可能会在接口允许的情况下使用更具体的定义来进行映射。使用您的实现,您可以执行诸如定义 TypeC 类、实现接口 IInterfaceA 之类的操作。此类将填充接口 IInterfaceA 并允许在 IMapper(IInterfaceA, IInterfaceB) 上使用。但实际的实现需要 TypeA 类,而不是 TypeC 类。

紫衣仙女

您AToBMapper需要具有特定 type 的输入TypeA,但您尝试将其转换为IMapper<IInterfaceA, IInterfaceB>,这将允许任何具有 type 的输入IInterfaceA。这是不可能的,因为其他具体类可以实现IInterfaceA,并且无法转换为TypeA。
随时随地看视频慕课网APP
我要回答