【问题标题】:Is there any workaround for CS0266: Cannot implicitly convert type ... (IList<Interface>)? [duplicate]CS0266 是否有任何解决方法:无法隐式转换类型...(IList<Interface>)? [复制]
【发布时间】:2019-12-24 22:52:21
【问题描述】:

我有一个实现接口的类。第二个类实现了第一个类的 IList。我需要将第二个类分配给一个通用属性,它是接口的 IList。

这是我使用的代码的演示:

public class SODemo
{
    public SODemo()
    {
        ClassWithIListOfClassWithInterface classWithIList = new ClassWithIListOfClassWithInterface();

        IList<IDemoInterface> listOfInterfaces;

        // CS0266: Cannot implicitly convert type ...
        listOfInterfaces = classWithIList;
    }
}

public class ClassWithInterface : IDemoInterface
{
    // ...
}

public class ClassWithIListOfClassWithInterface : IList<ClassWithInterface>
{
    // ...
}

从类似问题的答案中,我发现它似乎根本不起作用。

我为什么需要这个?
我有很多像ClassWithIListOfClassWithInterface 这样实现的类,我需要一个通用的处理程序。

问题:
我的目标是通过接口中实现的方法访问listOfInterfaces中的每个元素。

我可以使用任何替代方法吗?

编辑
这个我已经试过了

listOfInterfaces = (IList<IDemoInterface>)classWithIList;

然后我在运行时收到System.InvalidCastException

【问题讨论】:

  • 局部变量可以用IEnumerable代替ILIst吗?
  • @DStanley 不,我需要 Add() Remove() ... 东西,出于性能原因,我需要 List()
  • 那么你不能使用更通用的变量。基础列表将更加具体,并可能导致运行时错误(例如,尝试将 ClassWithInterface2 添加到 List&lt;ClassWithInterface&gt;)。变量类型只是告诉编译器允许对底层对象进行哪些操作。
  • @DStanley 感谢您的提示。这听起来令人不安。你有具体的例子吗?
  • 我不确定你的意思 - List&lt;Banana&gt; 不是 IList&lt;Fruit&gt;,因为你不能向它添加 Apple。因此,在您的情况下,您不能使用更通用的变量来引用更具体的集合。

标签: c# inheritance interface


【解决方案1】:

问题不在于您的课程本身,而在于IList&lt;IDemoInterface&gt;IList&lt;ClassWithInterface&gt; 之间的转换。

IList&lt;T&gt; 在 C# 中被称为 “在 T 中不变”。这意味着您不能直接在 IList&lt;T1&gt;IList&lt;T2&gt; 之间进行转换,即使它们具有继承关系。

您可以做的是创建一个IList&lt;IDemoInterface&gt; 并将源IList&lt;ClassWithInterface&gt; 中的每个元素复制到它。当然那样会比较麻烦,所以 LINQ 的做法是这样的:

listOfInterfaces = classWithIList.Cast<IDemoInterface>().ToList();

【讨论】:

  • 如果您需要更多信息,请查看these docs on variance (covariance and contravariane)。我还建议您使用 IEnumerable&lt;IDemoInterface&gt; 而不是 IList&lt;IDemoInterface&gt;,因为它对 LINQ 更友好,并且它使集合的评估变得懒惰,并且您的代码更通用。
  • 我知道问题的原因是什么。无法创建副本。
  • 请注意,这不会复制列表中的 items - 它会创建一个引用相同项目的 new 列表(只是通过不同的界面)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多