为什么接口类型列表不能接受继承接口的实例? [英] Why can't a list of an interface type accept instances of an inheriting interface?

查看:120
本文介绍了为什么接口类型列表不能接受继承接口的实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下类型:

public interface IPrimary{ void doBattle(); }

// an ISecondary "is" an IPrimary
public interface ISecondary : IPrimary {  }

// An implementation of ISecondary is also an IPrimary:
internal class SecondaryImpl : ISecondary
{
    // Required, since this is an IPrimary
    public void doBattle(){ }
}

为什么我不这样做?

List<IPrimary> list = new List<ISecondary>();

这会导致以下编译错误:

This results in the following compilation error:

参数类型'System.Collections.Generic.List'不能分配给参数类型'System.Collections.Generic.List'

Argument type 'System.Collections.Generic.List' is not assignable to parameter type 'System.Collections.Generic.List'

我理解错误,并且我意识到有解决方法。我只是没有看到任何明确的原因,为什么不允许这种直接转换。毕竟, ISecondary 列表中包含的值应该是(通过扩展名) IPrimary 类型的值。为什么列表< IPrimary> 列表< ISecondary> 被解释为不相关的类型?

I understand the error, and I realize there are workarounds. I just do not see any clear reason why this direct conversion is disallowed. The values contained in a list of ISecondary, should after all, be (by extension) values of type of IPrimary.Why then are List<IPrimary> and List<ISecondary> being interpreted as unrelated types?

任何人都可以清楚地解释以这种方式设计C#的原因吗?

稍微延长例如:我在尝试执行类似以下操作时遇到了这个问题:

A slightly extended example: I came across the issue when trying to do something similar to the following:

internal class Program
{
    private static void Main(string[] args)
    {
        // Instance of ISecondary, and by extention, IPrimary:
        var mySecondaryInstance = new SecondaryImpl();

        // This works as expected:
        AcceptImpl(mySecondaryInstance);

        // List of instances of ISecondary, which are also, 
        // by extention, instances of IPrimary:
        var myListOfSecondaries = new List<ISecondary> {mySecondaryInstance};

        // This, however, does not work (results in a compilation error):
        AcceptList(myListOfSecondaries);
    }

    // Note: IPrimary parameter:
    public static void AcceptImpl(IPrimary instance){  }

    // Note: List of type IPrimary:
    public static void AcceptList(List<IPrimary> list){  }

}


推荐答案


为什么我不这样做? 列表与LT; IPRIMARY> list = new List< ISecondary>();

想象一下,你有一个像这样定义的方法:

Imagine that you had a method defined like this:

public void PopulateList(List<IPrimary> listToPopulate)
{
    listToPopulate.Add(new Primary());  // Primary does not implement ISecondary!
}

如果您传递会怎样?列表< ISecondary> 作为参数?

错误 列表< ISecondary> 不能从列表中分配< IPrimary> 是编译器让你摆脱这些麻烦的方法。

The error that List<ISecondary> is not assignable from List<IPrimary> is the compiler's way of getting you out of such troubles.

这篇关于为什么接口类型列表不能接受继承接口的实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆