If you are writing such an API,wrap the array in a ReadOnlyCollection and return an IEnumerable or an IList or something,but not an array. (And of course,do not simply cast the array to IEnumerable and think you’re done! That is still passing out variables; the caller can simply cast back to array! Only pass out an array if it is wrapped up by a read-only object.)
所以我搞砸了一大堆:
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个新引用,而不是像ToArray()返回一个新的数组,而不是创建一个新的IEnumerable.
当我比较数组和IEnumerable的接口时,它们都具有相同的接口.为什么数组没有实际执行任何操作呢?我知道AsEnumerable()具有与Linq-to-entities的用途,以便在获得IQueryable时获取可枚举的方法,但为什么会将此方法添加到数组?这种方法有什么实际用途吗?
编辑:Tim Schmelter的这个评论提出了一个非常好的一点,不应该被忽视:
“这不是没用,你可以改变实际的类型,而不会破坏其余的代码,所以你可以用数据库查询或者列表或者hashset或者其他代替数组,但是AsEnumerable总是可以工作,其余的代码也是所以AsEnumerable就像一个合同.“
解决方法
public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source) { return source; }
它根本没有创建一个新对象.
原因很有用:
>如果对象实现IEnumerable< T>而且还有一个名为Select,Where等的实例方法,不能使用LINQ方法. AsEnumerable可以将其转换为IEnumerable,以避免这种过载冲突.>如果要将对象投射到IEnumerable< T> (无论什么原因),但是T是一个匿名类型,你不能使用一个转换,你需要一个通用的方法来推断它的泛型参数.