【发布时间】:2015-12-10 13:55:04
【问题描述】:
我正在阅读 Eric Lippert 的 a blog,他解释了为什么他几乎从不使用数组,以下部分让我很好奇:
如果您正在编写这样的 API,请将数组包装在 ReadOnlyCollection 中并返回 IEnumerable 或 IList 或其他内容,但不返回数组。 (当然,不要简单地将数组转换为 IEnumerable 并认为你已经完成了!这仍然是传递变量;调用者可以简单地转换回数组!如果它只传递一个数组被一个只读对象包裹起来。)
所以我有点搞乱收藏:
string[] array = new[] { "cat", "dog", "parrot" };
IEnumerable<string> test1 = array.AsEnumerable();
string[] secondArray = (string[])test1;
//array1[0] is now also "whale"
array[0] = "whale";
//11 interfaces
var iArray = array.GetType().GetInterfaces();
//Still 11 interfaces??
var iTest1 = test1.GetType().GetInterfaces();
我初始化一个数组,然后在其上使用AsEnumerable() 方法将其转换为IEnumerable(或者我认为是这样),但是当我将它转换回一个新数组并更改原始值时数组,test1 和 secondArray 的值被更改为。显然,我只是对原始数组进行了 2 次新引用,而不是创建一个新的 IEnumerable,有点像 ToArray() 返回一个新数组。
当我比较数组和IEnumerable 的接口时,它们都有相同的接口。如果数组实际上根本没有做任何事情,为什么还要使用该方法?我知道AsEnumerable() 与Linq-to-entities 一起使用,可以在您拥有IQueryable 时获取可枚举的方法,但是为什么要将此方法添加到数组中呢?这种方法有实际用途吗?
编辑: Tim Schmelter 的评论提出了一个非常好的观点,不应忽视:
“它不是那么没用。您可以更改实际类型而不会破坏其余代码。因此您可以将数组替换为数据库查询或列表或哈希集或其他任何东西,但 AsEnumerable 始终有效并且其余的代码也在后面。所以 AsEnumerable 就像一个合同。”
【问题讨论】:
-
The AsEnumerable<TSource>(IEnumerable<TSource>) method has no effect other than to change the compile-time type of source from a type that implements IEnumerable<T> to IEnumerable<T> itself.msdn.microsoft.com/library/bb335435(v=vs.100).aspx -
上面的含义(我引用的)意味着您可以以不同的方式迭代它。不确定它还提供什么。
-
AsEnumerable()不是数组的方法。这是IEnumerable<T>的扩展方法。因为数组恰好实现了IEnumerable<T>,所以你可以在数组上调用它。 -
@AlexanderDerck 该方法在那里,因为它是 IEnumerable 上的扩展方法,并且数组实现了 IEnumerable。
标签: c# collections