将一个具体类型的ICollection转换为该具体类型接口的ICollection

4

如何将实现了 IBar 接口的 ICollection<Bar> 转换为 ICollection<IBar> 接口建议使用什么方法?

是不是很简单,只需要使用下面的代码:

collection = new List<Bar>();
ICollection<IBar> = collection as ICollection<IBar>?

还有更好的方法吗?

1
这并不完全是一个确切的副本,但请阅读 https://dev59.com/dGcs5IYBdhLWcg3wHwfU 了解为什么您的解决方案行不通。(它已经有语法错误了,但即使没有,它也会给出null作为as运算符的结果。) - Jon Skeet
2
你不能将类型转换为 ICollection<IBar>,但是你可以将其转换为 IEnumerable<IBar> - Henrik
@HenkHolterman 是的,谢谢。我现在看到其他答案都没有提到这种可能性。 - Henrik
3个回答

3

您需要将列表中的每个项目进行强制转换并创建一个新的项目,例如使用Cast

ICollection<IBar> ibarColl = collection.Cast<IBar>().ToList();

在.NET 4中,使用IEnumerable<T>的协变:
ICollection<IBar> ibarColl = collection.ToList<IBar>();

或者使用List.ConvertAll方法:

ICollection<IBar> ibarColl = collection.ConvertAll(b => (IBar)b);

后者可能会更有效率,因为它事先知道大小。

那会创建原始列表的一个副本。有没有一种方法可以重复使用相同的ICollection<T>实例来添加项目和操作集合? - Shimmy Weitzhandler
只有当它是 IList<T> 的实例,例如数组或列表时,才可以使用 for 循环替换它们,或者使用 Array.ConvertAll 或 list.ConvertAll,如答案所示。 - Tim Schmelter

2

你无法将类型转换为 ICollection<IBar>,但是你可以转换为 IEnumerable<IBar>

因此,如果你不打算向列表中添加任何内容,你可以这样做:

IEnumerable<IBar> enumeration = (IEnumerable<IBar>)collection;

其他答案中的解决方案实际上不会进行强制转换,而是创建一个新列表,它将不反映对原始列表的后续更改。


0

只需将所有条目转换为

ICollection<IBar> ibars = collection.ConvertAll(bar => (IBar)bar);

我认为这种变体也是可读的。也许有更高性能的转换方式...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接