Страницы

Поиск по вопросам

четверг, 11 октября 2018 г.

C# Оператор “return _();”

Здравствуйте. Требуется включить в проект Visual Studion 2015 Community исходный код из проекта MoreLinq. Попытался запустить sulution и скомпилировать проекты, но проекты даже не загрузились, возникает следующая ошибка:
C:\Users
ostov.d\Desktop\MoreLINQ-master\MoreLinq\MoreLinq.csproj : error : пространством имен XML по умолчанию для этого проекта должно быть пространством имен MSBuild XML. Если проект создан в формате MSBuild 2003, добавьте xmlns="http://schemas.microsoft.com/developer/msbuild/2003" в элемент . Если проект был создан в старом формате 1.0 или 1.2, преобразуйте его в формат MSBuild 2003. C:\Users
ostov.d\Desktop\MoreLINQ-master\MoreLinq\MoreLinq.csproj
Попытался скопировать только нужные файлы исходного кода в свой проект и скомпилировать. Но Visual Studio ругается на конструкции такого типа:
return _(); IEnumerable _()
Подозреваю, что это связано с отложенным выполнением Linq запросов. В интернете документации найти не смог. Что это за конструкция "return"_(); и как скомпилировать такой код под Visual Stuio 2015 Community? Пример функции с таким return:
public static IEnumerable Exclude(this IEnumerable sequence, int startIndex, int count) { if (sequence == null) throw new ArgumentNullException(nameof(sequence)); if (startIndex < 0) throw new ArgumentOutOfRangeException(nameof(startIndex)); if (count < 0) throw new ArgumentOutOfRangeException(nameof(count));
return _(); IEnumerable _() { var index = -1; var endIndex = startIndex + count; using (var iter = sequence.GetEnumerator()) { // yield the first part of the sequence while (iter.MoveNext() && ++index < startIndex) yield return iter.Current; // skip the next part (up to count items) while (++index < endIndex && iter.MoveNext()) continue; // yield the remainder of the sequence while (iter.MoveNext()) yield return iter.Current; } } }


Ответ

Тут используется объявление вложенного метода:
IEnumerable _()
Это просто метод без параметров, который имеет имя _ и возвращает IEnumerable
return _();
А тут возвращается результат вызова этого метода.
Из-за использования yield return метод не начнёт выполняться до того, как произойдёт обращение к первому элементу возвращаемой последовательности. Однако, автор хотел, чтобы секция валидации входных данных
if (sequence == null) throw new ArgumentNullException(nameof(sequence)); if (startIndex < 0) throw new ArgumentOutOfRangeException(nameof(startIndex)); if (count < 0) throw new ArgumentOutOfRangeException(nameof(count));
исполнялась немедленно, поэжтому она должна находиться в методе, не содержащем yield return. Т. о. весь метод распадается на два.
И немного ссылок:
Когда предусловия не являются предусловиями Итераторы в языке C#. Часть 1 Итераторы в языке C#. Часть 2 Итераторы в языке C#. Часть 3 ErrorProne.NET. Часть 3 Новшества C# 7 Для чего действительно нужны локальные функции? Объясните смысл новшеств C# 7

Комментариев нет:

Отправить комментарий