【问题标题】:Cannot assign a derived class to its parent generic interface无法将派生类分配给其父泛型接口
【发布时间】:2019-12-17 07:40:09
【问题描述】:

我正在尝试分配一个从派生类继承的类,但 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

考虑到TypeAIInterfaceATypeBIInterfaceB ?,这不应该是可能的吗

【问题讨论】:

    标签: c# inheritance interface covariance contravariance


    【解决方案1】:

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

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

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

    【讨论】:

    • 感谢您的解释,这完全有道理。
    【解决方案2】:

    您的AToBMapper 需要具有特定类型TypeA 的输入,但您正试图将其转换为IMapper&lt;IInterfaceA, IInterfaceB&gt;,这将允许任何具有IInterfaceA 类型的输入。

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

    【讨论】:

    • 是的,既然您和@JokoFacile 已经发布了回复,这很有意义。感谢您清除此问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    • 1970-01-01
    • 2019-10-03
    • 2016-11-15
    • 1970-01-01
    • 2011-10-09
    相关资源
    最近更新 更多