Задайте несколько значений класса с помощью выражения LINQ

#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. Спасибо!