c# - 在接口(interface)内部声明 IEnumerable<T>,同时在具体类中声明 IList<T>

标签 c# .net generics interface ienumerable

考虑一个例子:

我有一个这样的界面。我需要这个接口(interface)是协变的 - 这意味着我必须将我的泛型声明为“out”并使用 IEnumerable 而不是列表 - 仅此而已。我将用它来简单地获取我需要的元素 - 无需插入任何内容。

    public interface IFoo<out T>
    {
          IEnumerable<T> Items { get; } 
    }

然后我的具体类声明如下:

    public class Foo : IFoo<Item>
    {
         // I have an error here : Type IList doesn't match the expected type IEnmerable
          IList<Item> Items { get; set; } 
    }

我想知道为什么这是不可能的?我的意思是 IList 继承自 IEnumerable 并且这种类型的代码完全可以正常工作。

public IEnumerable<Item> GetItems()
{
    return new List() { new Item())};
}

为什么可以做到?有哪些解决方法?

我唯一的解决方案是我可以像这样创建额外的属性或方法

public IEnumerable<Item> GetEnumerableItems()
{
   return Items;
}

但这对我来说似乎太老套了。我认为可能有一个更清洁的解决方案。

最佳答案

运行时不支持此功能。如果您要实现的接口(interface)具有返回特定类型的属性,则必须在实现中完全匹配该返回类型。

Return Type Covariance已在 C# 9 中添加,但此处不适用(请参阅@JeroenMostert 的评论)。

您可以通过使用显式接口(interface)实现来解决此问题:

public class Foo : IFoo<Item>
{
    IList<Item> Items { get; set; }
    IEnumerable<Item> IFoo<Item>.Items => Items;
}

SharpLab .

拥有 Foo 的消费者可以访问Foo.Items并获得 IList<Item> 。刚刚拥有 IFoo<Item> 的消费者可以访问 IFoo<Item>.Items ,并将返回 IEnumerable<Item> .

关于c# - 在接口(interface)内部声明 IEnumerable<T>,同时在具体类中声明 IList<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71408984/

相关文章:

c# - 序列化代码的最佳位置。正在序列化的类的内部,还是按格式的外部类?

c# - 在构造函数中将整数字段/属性分配为零

c# - 根据窗体大小在窗体上定位控件

java - java中如何转换泛型?

c# - 如何为我的程序获取 "enabled functions"许可证文件?

c# - Win32_EncryptableVolume 在 C# 中获取 bitlocker 状态

c# - JIT 或 CLR 中可能存在的错误

c# - ConfigurationManager.ConnectionStrings.Add

.net - 有机会合法投吗?

Kotlin 通用接口(interface)解析器