#c# #linq
#c# #linq
Вопрос:
У меня есть следующие два оператора LINQ, которые устанавливают разные значения в одном и том же элементе в списке
List<MyClass> myList = GetList();
myList.Where(x => x.Name == "someName").Select(x => x.MyArray = someList.ToArray()).ToList();
myList.Where(x => x.Name == "someName").Select( x => x.AnotherValue = GetValue()).ToList();
Можно ли объединить это, чтобы оба были установлены в одном выражении?
Комментарии:
1. В идеале, не делайте этого вообще. Используйте
foreach
цикл. Включение побочных эффектов вSelect
предложения, подобные this, на самом деле не так, как предполагалось использовать LINQ.
Ответ №1:
myList
.Where(x => x.Name == "someName")
.ToList()
.ForEach(x => {
x.MyArray = someList.ToArray();
x.AnotherValue = GetValue();
});
Почему вы вызываете ToList()
в конце каждого из этих выражений и отбрасываете результат?
Кроме того, Джон Скит прав в том, что это злоупотребление LINQ, и особенно в вашей исходной форме: очевидно, что выражения LINQ даже не обязательно должны быть полностью перечислены. Тот факт, что вам нужны были эти ToList()
вызовы, чтобы что-то произошло, должен был вызвать у вас серьезное и неприятное чувство, что вы неправильно используете языковую функцию. Когда вам нужно сделать что-то странное, чтобы использовать выбранную вами конструкцию вместо обычного способа сделать это, доведите ее до работы (потому что странно — это круто), а затем вернитесь и переделайте ее скучным, убогим способом, прежде чем проверять ее.
Какое преимущество вы видите в версии LINQ ForEach()
выше по сравнению с этой версией?
foreach (var x in myList.Where(x => x.Name == "someName"))
{
x.MyArray = someList.ToArray();
x.AnotherValue = GetValue();
}
Версия цикла в старом стиле короче, понятна сразу, потому что это идиома по умолчанию, и ИМО чище. Вам не обязательно делать все с помощью LINQ.
Примечание: ForEach()
это не LINQ; это член List<T>
. Вот почему вы должны вызвать ToList()
, чтобы использовать его.
Комментарии:
1. Он звонит
ToList
, по-видимому, для выполненияSelect
🙂
Ответ №2:
Просто используйте лямбда-оператор для передачи всего лямбда-выражения, определенного внутри {...}
блока:
myList.Where(x => x.Name == "someName").Select(x => { x.MyArray = someList.ToArray(); x.AnotherValue = GetValue(); return x;}).ToList();
Комментарии:
1. Лямбда-выражение Select
Func<T,TReturn>
; что оно возвращает в вашем примере?2. @EdPlunkett действительно, я забыл об операторе return. Спасибо!