linq中数组和列表之间的集合变化之间的差异

时间:2017-04-28 21:32:05

标签: c# arrays list linq collections

我在linq和集合之间的交互中发现了行为,我无法理解。

我被教导,通过此集合枚举期间更改集合会导致InvalidOperationException。

但这有点复杂。

我有一个例子heremirror

using System;
using System.Collections.Generic;
using System.Linq; 

public class Program
{
        public void Main()
        {
            Program.Try(Program.HandleArray_Where, "array.where");
            Program.Try(Program.HandleArray_Where_OrderBy, "array.where.orderby");
            Program.Try(Program.HandleList_Where, "list.where");
            Program.Try(Program.HandleList_Where_OrderBy, "list.where.orderby");
        }

        private static void Try(Action action, string text)
        {
            Console.WriteLine(text);

            try
            {
                action.Invoke();
            }
            catch (InvalidOperationException)
            {
                Console.WriteLine("Invalid operation");
            }

            Console.WriteLine();
            Console.WriteLine();
        }

        private static void HandleArray_Where()
        {
            IList<int> arr = new[] { 1, 2, 3, 4, 5 };
            var enumerable = arr.Where(item => item > 2);

            foreach (var item in enumerable)
            {
                arr[3] = 0;

                Console.WriteLine(item);
            }
        }

        private static void HandleArray_Where_OrderBy()
        {
            IList<int> arr = new[] { 1, 2, 3, 4, 5 };
            var orderedEnumerable = arr.Where(item => item > 2).OrderBy(asd => asd);

            foreach (var item in orderedEnumerable)
            {
                arr[3] = 0;

                Console.WriteLine(item);
            }
        }

        private static void HandleList_Where()
        {
            IList<int> list = new List<int> { 1, 2, 3, 4, 5 };
            var enumerable = list.Where(item => item > 2);

            foreach (var item in enumerable)
            {
                list[3] = 0;

                Console.WriteLine(item);
            }
        }

        private static void HandleList_Where_OrderBy()
        {
            IList<int> list = new List<int> { 1, 2, 3, 4, 5 };
            var orderedEnumerable = list.Where(item => item > 2).OrderBy(asd => asd);

            foreach (var item in orderedEnumerable)
            {
                list[3] = 0;

                Console.WriteLine(item);
            }
        }
}

有四个集合,我试图在枚举期间更改它们。我应该有四次InvalidOperationException,但我只有一次。

输出:

array.where
3
5


array.where.orderby
3
4
5


list.where
3
Invalid operation


list.where.orderby
3
4
5

所以,我可以解释这样的结果:

.OrderBy()使用.Where()的结果,使用新的集合,不会感觉到原始集合的变化,因为样本是在更改之前拍摄的。所以在块“array.where.orderby”和“list.where.orderby”中有三个数字。

但是我不理解“array.where”和“list.where”块的行为。为什么我可以在迭代期间更改int[]并且无法更改List<int>,尤其是如果它们都转换为IList<int>?现在我认为这是与Liskov替换原则的差异:一个父类型有两种不同的行为,具体取决于变量的真实类型

0 个答案:

没有答案