考虑一个例子:
我有一个这样的界面。我需要这个接口(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/