Date: 29.06.2019 14:27:41
Date: 29.06.2019 16:20:22
Тут все упирается в то, как работают Select и LastOrDefault. Возьмите следующий код:
using System; using System.Collections.Generic; using System.Linq; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var array = new int[] { 1, 2, 3 }; var sel = array.Select((x) => { Console.WriteLine(x.ToString() + " selected"); return x; }); var t = sel.GetType(); Console.WriteLine("Select iterator type: "+t.ToString()+"\n"); Console.WriteLine("Select iterator interfaces: "); Console.WriteLine(String.Join("\n", t.GetInterfaces().Select(x => x.ToString()))); Console.WriteLine("\nLastOrDefault: "+sel.LastOrDefault()); } } }
При запуске в .NET Framework он даст такой результат:
Select iterator type: System.Linq.Enumerable+WhereSelectArrayIterator`2[System.Int32,System.Int32]При запуске под .NET Core:
Select iterator type: System.Linq.Enumerable+SelectArrayIterator`2[System.Int32,System.Int32]
Select iterator interfaces:
System.Collections.Generic.IEnumerable`1[System.Int32]
System.Collections.IEnumerable
System.Collections.Generic.IEnumerator`1[System.Int32]
System.IDisposable
System.Collections.IEnumerator
System.Linq.IPartition`1[System.Int32]
System.Linq.IIListProvider`1[System.Int32]
3 selected
LastOrDefault: 3
Как видно, в .NET Core результатом Select является совершенно другой тип, который реализует интерфейс IPartition. Метод LastOrDefault содержит оптимизацию, которая заставляет его, если тип итератора реализует IPartition, не вычислять всю последовательность, я сразу брать ее последний элемент (это видно, если в выражение Select поместить вывод). Таким образом, ваш код, который рассчитывал на вычисление всей последовательности, ломается.
Автор: VadimTagil