【问题标题】:List of interface D that implements interface B Can't be recognized as List<B>实现接口 B 的接口 D 列表不能被识别为 List<B>
【发布时间】:2019-03-07 18:08:31
【问题描述】:

我有一个接口 ID,它是从另一个接口 IB 派生的。

public interface IB
{
    int Num { get; }
}

public interface ID : IB
{

}

假设我们有一个实现 ID 的类:

public class DImpl : ID
{
     public int Num { get; set; }
}

我知道我可以调用一个接收 IB 的函数,该函数带有一个作为 ID 保存的变量。

public void FuncOfIB(IB b)
{
     // do something
}

public static void Main()
{
     ID d = new DImpl();
     FuncOfIB(d); // Works
}

我想调用一个接收List&lt;IB&gt;作为参数的函数:

void ProcessListOfIB(List<IB> list)
{
   // Some code
}

但是我好像不能用List&lt;ID&gt;调用这个函数。

public static void Main()
{
     List<ID> listID = new List<ID>();
     ProcessListOfIB(listID); // Doesn't work
}

有人知道为什么吗?我该如何解决?谢谢。

编辑:我需要函数ProcessListOfIB 从列表中删除一个项目,所以复制并不能解决我的问题...

【问题讨论】:

  • 您可以使用 linq 解决此问题:listD.Cast&lt;IB&gt;().ToList()
  • 问题是我希望函数 ProcessListOfIB() 将删除原始列表中的成员。我将编辑我的原始帖子
  • List 允许您添加项目,因此ProcessListOfIB 可能会调用list.Add(x),其中x 的类型为IB。这意味着您的列表将不再完全由 ID 项目组成。简而言之,这就是不允许隐式转换的原因。
  • 那么,您的 ProcessListOfIB 方法中的代码真的需要 List 吗?它可能会对 IEnumerable 类型的方法参数感到满意吗?如果您的 ProcessListOfIB 方法可以使用 IEnumerable 而不是 List,则使用使用 IEnumerable 的方法参数。通过这种方式,该方法不仅可以与其他集合类型一起使用,而且由于 IEnumerable 中的泛型类型参数为 covariant,您的问题就会消失。

标签: c#


【解决方案1】:

您可以创建 Generic 方法并将类型限制为 IB:

void ProcessListOfIB<T>(List<T> list) where T:IB
{
    // Some code
}

【讨论】:

    【解决方案2】:

    如果你只需要遍历集合(而不是修改它):

    void ProcessListOfIB(IEnumerable<IB> list)
    {
        // Some code
    }
    

    【讨论】:

      【解决方案3】:

      列表没有被标记为既不协变也不逆变(因为它不可能,它不是接口),所以这就是它不起作用的原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-07-26
        • 2015-01-15
        • 1970-01-01
        • 1970-01-01
        • 2014-11-02
        • 2013-04-14
        • 2014-10-31
        相关资源
        最近更新 更多