Есть ли способ сделать следующее с помощью LINQ?
foreach (var c in collection)
{
c.PropertyToSet = value;
}
Чтобы уточнить, я хочу перебрать каждый объект в коллекции, а затем обновить свойство для каждого объекта.
Мой вариант использования - у меня есть куча комментариев к сообщению в блоге, и я хочу перебрать каждый комментарий к сообщению в блоге и установить дату и время в сообщении в блоге на +10 часов. Я мог бы сделать это в SQL, но я хочу сохранить это на бизнес-уровне.
Я пришел сюда в поисках ответа на тот же вопрос и решил, что это так же просто, меньше кода и легче понять будущим разработчикам, просто сделать это так, как вы сделали в своем OP.
Зачем вам это нужно делать в LINQ?
Этот вопрос задает неправильный вопрос, единственный правильный ответ: не используйте LINQ для изменения источника данных.
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что почти все ответы на этот вопрос активно вредят пониманию LINQ новыми программистами.
@TimSchmelter что-то не так с вашим комментарием в качестве ответа? Потому что это ответ, скорее всего или нет.





Для этого нет встроенного метода расширения. Хотя определить одно довольно просто. Внизу поста находится метод, который я определил под названием Iterate. Его можно использовать так
collection.Iterate(c => { c.PropertyToSet = value;} );
Итерировать источник
public static void Iterate<T>(this IEnumerable<T> enumerable, Action<T> callback)
{
if (enumerable == null)
{
throw new ArgumentNullException("enumerable");
}
IterateHelper(enumerable, (x, i) => callback(x));
}
public static void Iterate<T>(this IEnumerable<T> enumerable, Action<T,int> callback)
{
if (enumerable == null)
{
throw new ArgumentNullException("enumerable");
}
IterateHelper(enumerable, callback);
}
private static void IterateHelper<T>(this IEnumerable<T> enumerable, Action<T,int> callback)
{
int count = 0;
foreach (var cur in enumerable)
{
callback(cur, count);
count++;
}
}
Необходима ли итерация, что не так с Count, Sum, Avg или другим существующим методом расширения, который возвращает скалярное значение?
это довольно близко к тому, что я хочу, но немного ... вовлечено. Сообщение в блоге, которое я опубликовал, имеет аналогичную реализацию, но с меньшим количеством строк кода.
IterateHelper кажется излишним. Перегрузка, которая не принимает индекс, в конечном итоге выполняет гораздо больше дополнительной работы (преобразование обратного вызова в лямбду, которая принимает индекс, ведение счетчика, который никогда не используется). Я понимаю, что это повторное использование, но это обходной путь для простого использования forloop, поэтому он должен быть эффективным.
@Cameron, IterateHelper служит двум целям. 1) Единая реализация и 2) позволяет генерировать исключение ArgumentNullException во время вызова по сравнению с использованием. Итераторы C# выполняются с задержкой, поскольку помощник предотвращает странное поведение исключения во время итерации.
@JaredPar: за исключением того, что вы не используете итератор. Нет заявления о доходности.
@Cameron, Doh, это часть коллекции методов расширения, которыми я владею, и это единственный метод, который не использует итератор. В любом случае дополнительные накладные расходы незначительны.
Нет, LINQ не поддерживает способ массового обновления. Единственный способ короче - использовать метод расширения ForEach - Почему в IEnumerable нет метода расширения ForEach?
Я предполагаю, что вы хотите изменить значения внутри запроса, чтобы вы могли написать для него функцию
void DoStuff()
{
Func<string, Foo, bool> test = (y, x) => { x.Bar = y; return true; };
List<Foo> mylist = new List<Foo>();
var v = from x in mylist
where test("value", x)
select x;
}
class Foo
{
string Bar { get; set; }
}
Но не сомневайтесь, если это вы имеете в виду.
Это идет в правильном направлении, потребовалось бы что-то для перечисления v, иначе это ничего не сделает.
Мои 2 копейки: -
collection.Count(v => (v.PropertyToUpdate = newValue) == null);
Мне нравится думать, но не совсем понятно, что делает код
Я действительно нашел метод расширения, который будет делать то, что я хочу, красиво
public static IEnumerable<T> ForEach<T>(
this IEnumerable<T> source,
Action<T> act)
{
foreach (T element in source) act(element);
return source;
}
хорошо :) Lomaxx, может быть, добавить пример, чтобы люди могли видеть его в «действии» (бум-тиш!).
Это единственный полезный подход, если вы действительно хотите избежать цикла foreach (по какой-либо причине).
@Rango, который вы по-прежнему НЕ избегаете foreach, поскольку сам код содержит цикл foreach
@GoldBishop конечно, метод скрывает петлю.
Ссылка не работает, теперь она доступна по адресу: codewrecks.com/blog/index.php/2008/08/13/…. Также есть комментарий в блоге, который ссылается на stackoverflow.com/questions/200574. В свою очередь, комментарий верхнего вопроса ссылается на blogs.msdn.microsoft.com/ericlippert/2009/05/18/…. Возможно, ответ будет проще переписать с использованием MSDN (вы все равно можете указать первую ссылку, если хотите). Замечание: Rust имеет аналогичные функции, но в конце концов уступил и добавил эквивалентную функцию: stackoverflow.com/a/50224248/799204.
В блоге MSDN sourcejedi по ссылке blogs.msdn.microsoft.com/ericlippert/2009/05/18/… есть хорошее объяснение того, почему автор подумал, что создание такого метода расширения - плохая идея. Для меня наиболее убедительная причина автора заключается в том, что использование такого метода расширения на самом деле не экономит много нажатий клавиш по сравнению с простым циклом foreach. Шлейф: foreach(Foo foo in foos){ statement involving foo; } Метод расширения: foos.ForEach((Foo foo)=>{ statement involving foo; });
Хотя вы можете использовать метод расширения ForEach, если вы хотите использовать только фреймворк, вы можете сделать
collection.Select(c => {c.PropertyToSet = value; return c;}).ToList();
ToList необходим для немедленной оценки выбора из-за ленивая оценка.
Я проголосовал за это, потому что это довольно хорошее решение ... единственная причина, по которой мне нравится метод расширения, заключается в том, что он делает его немного более ясным, чтобы понять, что именно происходит ... однако ваше решение все еще довольно мило
Я согласен, мой ответ в основном для тех, кто не хочет использовать метод расширения.
Если мы все равно создаем список, не можем ли мы просто набрать: collection.ToList (). ForEach (c => c.PropertyToSet = value);
Если, скажем, коллекция была ObservableCollection, то может оказаться полезным изменение элементов на месте, а не создание нового списка.
+1 Мне помогли. Resharper просит удалить .ToList () в конце. Там написано Return value of pure method is not used.
@desaivv да, это немного злоупотребление синтаксисом, поэтому Resharper предупреждает вас об этом.
Я пробовал это, но все время получаю ошибку компилятора: A lambda expression with a statement body cannot be converted to an expression tree. Когда я извлек его на Func, все снова было в порядке. Почему это?
@KonradMorawski Вы делаете выбор в IQueryable, а не в IEnumerable, поэтому, скорее всего, LINQ to SQL. Это работает только с LINQ to objects.
@CameronMacFarland ах, ты прав. Спасибо за ответ!
это был ToList() ... спасибо за указатель!
Что, если мы захотим использовать с этим оператор «где»?
IMHO, это гораздо менее выразительно, чем простой цикл foreach. ToList () сбивает с толку, потому что он не используется ни для чего, кроме принудительной оценки, которая в противном случае была бы отложена. Проекция также сбивает с толку, потому что она используется не по прямому назначению; скорее, он используется для перебора элементов коллекции и предоставления доступа к свойству, чтобы его можно было обновить. Единственный вопрос, который у меня в голове, будет заключаться в том, может ли цикл foreach выиграть от параллелизма с использованием Parallel.ForEach, но это другой вопрос.
+1 за упоминание о ленивой оценке. Мне это помогло.
Хороший ... Это решение позволяет использовать гибкий синтаксис (функции связывания). Расширение ForEach - нет.
В этом случае LINQ быстрее, чем foreach?
@ Pan.student, черт возьми, нет. Честно говоря, я не уверен, что когда-нибудь буду использовать эту технику.
может кто-нибудь объяснить мне внутренний код return c;, пожалуйста?
@ ShiftN'Tab: Лямбда-выражения обычно содержат один оператор, например x => x.Id. Однако им разрешено иметь несколько утверждений. В этом случае вам нужно использовать фигурные скобки вокруг нескольких операторов. Кроме того, если вам нужно вернуть значение из лямбда-выражения с несколькими операторами, вы должны использовать оператор return. В приведенном выше примере используется лямбда-выражение с несколькими операторами: c => {c.PropertyToSet = value; return c;}. В нем есть 2 оператора, которые для ясности вы обычно пишете в разных строках: c.PropertyToSet = value; и return c;. Это очень похоже на анонимный метод C# 2.0.
Может кто-нибудь объяснить, почему этот ответ получил наибольшее количество голосов? Почему это лучше, чем использовать ForEach?
@CameronMacFarland. что означает "return c;"? это обязательно? не можем мы сделать это без "return c"; как в примере foreach?
Я шокирован, что это ответ номер 1, за который так много голосов. Поддерживать этот код было бы настоящим кошмаром. Зачем использовать select, если можно просто использовать ForEach ?? Даже двухстрочный синтаксис цикла for легче написать, и он гораздо более выразителен в отношении того, что делает код. Ради любви к Богу, пожалуйста, не делайте этого в своем кодексе !!
Этот код изменяет коллекцию во время работы с ней. Select действительно должен быть неизменным и избегать подобных побочных эффектов. ToList также вызывает выделение другой коллекции. По сути, этот код не делает того, что кажется на первый взгляд; любой, кто знаком со сканированием LINQ, не ожидает, что коллекция будет изменена.
Рассмотрим blogs.msdn.microsoft.com/ericlippert/2009/05/18/…
@EricLippert, пожалуйста, поясните, почему это не лучшая практика?
Ознакомьтесь со всеми другими комментариями, чтобы узнать, почему это плохая идея. Вы никогда не должны использовать select для выполнения побочного эффекта. Цель выбора - выбрать значение, а не имитировать a для каждого цикла.
как я могу использовать тернарный оператор для условного присвоения значения? var test = dataSet.Select(f => { (some condition here)? f.Type = "Masked" : f.Type; return f; }).ToList();
@CodeRunner Публикуя это как новый вопрос, а не как комментарий к ответу. В любом случае, тернарный код предполагает, что оба выражения могут быть вычислены для одного и того же типа. Я сомневаюсь, что вам понадобится что-нибудь для вашей задачи. Вместо этого используйте простую нулевую проверку и назначьте f.Type = "Masked" только в этом случае.
Это решение работает только в том случае, если коллекция уже является списком до применения фильтров. Если вы попытаетесь использовать коллекцию как IEnumerable, она не будет работать, даже если вы добавите .ToList () в конце.
В VS2017 я получаю ошибки компилятора CS0832 и CS0834, когда делаю это так.
Вы можете использовать LINQ для преобразования вашей коллекции в массив, а затем вызвать Array.ForEach ():
Array.ForEach(MyCollection.ToArray(), item=>item.DoSomeStuff());
Очевидно, это не будет работать с коллекциями структур или встроенными типами, такими как целые числа или строки.
Вы можете использовать Magiq, платформу пакетных операций для LINQ.
Вот метод расширения, который я использую ...
/// <summary>
/// Executes an Update statement block on all elements in an IEnumerable of T
/// sequence.
/// </summary>
/// <typeparam name = "TSource">The source element type.</typeparam>
/// <param name = "source">The source sequence.</param>
/// <param name = "action">The action method to execute for each element.</param>
/// <returns>The number of records affected.</returns>
public static int Update<TSource>(this IEnumerable<TSource> source, Func<TSource> action)
{
if (source == null) throw new ArgumentNullException("source");
if (action == null) throw new ArgumentNullException("action");
if (typeof (TSource).IsValueType)
throw new NotSupportedException("value type elements are not supported by update.");
var count = 0;
foreach (var element in source)
{
action(element);
count++;
}
return count;
}
Почему «элементы типа значения не поддерживаются обновлением» ?? Этому ничего не мешает!
Это было характерно для проекта, над которым я работал. Полагаю, в большинстве случаев это не имело бы значения. В последнее время я переработал это и переименовал его в Run (...), удалил тип значения и изменил его, чтобы вернуть void, и сбросил код счета.
Это более или менее то же самое, что и List<T>.ForEach, но только для всех IEnumerable.
Оглядываясь назад, я бы сказал, просто используйте цикл foreach. Единственное преимущество использования чего-то вроде этого - если вы хотите связать методы вместе и вернуть перечислимое значение из функции, чтобы продолжить цепочку после выполнения действия. В противном случае это просто дополнительный вызов метода без всякой пользы.
Я пробовал несколько вариантов этого и продолжаю возвращаться к решению этого парня.
http://www.hookedonlinq.com/UpdateOperator.ashx
Опять же, это чужое решение. Но я скомпилировал код в небольшую библиотеку и довольно регулярно использую ее.
Я собираюсь вставить сюда его код на случай, если его сайт (блог) перестанет существовать в какой-то момент в будущем. (Нет ничего хуже, чем увидеть сообщение "Вот точный ответ, который вам нужен", Click и Dead URL.)
public static class UpdateExtensions {
public delegate void Func<TArg0>(TArg0 element);
/// <summary>
/// Executes an Update statement block on all elements in an IEnumerable<T> sequence.
/// </summary>
/// <typeparam name = "TSource">The source element type.</typeparam>
/// <param name = "source">The source sequence.</param>
/// <param name = "update">The update statement to execute for each element.</param>
/// <returns>The numer of records affected.</returns>
public static int Update<TSource>(this IEnumerable<TSource> source, Func<TSource> update)
{
if (source == null) throw new ArgumentNullException("source");
if (update == null) throw new ArgumentNullException("update");
if (typeof(TSource).IsValueType)
throw new NotSupportedException("value type elements are not supported by update.");
int count = 0;
foreach (TSource element in source)
{
update(element);
count++;
}
return count;
}
}
int count = drawingObjects
.Where(d => d.IsSelected && d.Color == Colors.Blue)
.Update(e => { e.Color = Color.Red; e.Selected = false; } );
Вы можете использовать Action<TSource> вместо создания дополнительного делегата. Однако на момент написания этого могло не быть доступно.
Да, в то время это была старая школа DotNet. Хороший комментарий, Фрэнк.
URL мертв! (Срок действия этого доменного имени истек) Хорошо, что я скопировал сюда код! #patOnShoulder
Проверка типа значения имеет смысл, но, возможно, было бы лучше использовать ограничение, например where T: struct, чтобы уловить это во время компиляции.
collection.ToList().ForEach(c => c.PropertyToSet = value);
@SanthoshKumar: используйте collection.ToList().ForEach(c => { c.Property1ToSet = value1; c.Property2ToSet = value2; });
@CameronMacFarland: Конечно, не будет, поскольку структуры неизменяемы. Но если очень хочется, можно и так: collection.ToList().ForEach(c => { collection[collection.IndexOf(c)] = new <struct type>() { <propertyToSet> = value, <propertyToRetain> = c.Property2Retain }; });
Это имеет преимущество перед ответом Кэмерона МакФарланда в том, что он обновляет список на месте, а не создает новый список.
Вау, этот ответ действительно бесполезен. Создание новой коллекции только для того, чтобы иметь возможность использовать цикл
@SimonTewsi Поскольку это набор объектов, список в любом случае следует обновлять на месте. Коллекция будет новой, но объекты в коллекции останутся прежними.
У меня проблема со списком, в котором не обновляются первый и последний объекты .. какие-нибудь подсказки?
@Erik Thysell Скопируйте сюда свой код. Вы использовали foreach?
Как можно добавить предложение Where? Спасибо
@Diego Объедините предложение Where перед ToList ().
Я делаю это
Collection.All(c => { c.needsChange = value; return true; });
Я считаю, что это самый чистый способ сделать это.
Этот подход, безусловно, работает, но он нарушает цель метода расширения All(), что приводит к потенциальной путанице, когда кто-то читает код.
Этот подход лучше. Использование All вместо использования каждого цикла
Определенно предпочитайте это без необходимости вызывать ToList (), даже если это немного вводит в заблуждение относительно того, для чего он использует All ().
Если вы используете такую коллекцию, как List<>, в которой она есть, метод ForEach() - гораздо менее загадочный способ сделать это. ex ForEach(c => { c.needsChange = value; })
Это лучше, чем использование Select с ToList.
Использовать:
ListOfStuff.Where(w => w.Thing == value).ToList().ForEach(f => f.OtherThing = vauleForNewOtherThing);
Я не уверен, злоупотребляет ли это LINQ или нет, но это сработало для меня, когда я хотел обновить определенные элементы в списке для определенного условия.
Я написал несколько методов расширения, чтобы помочь мне в этом.
namespace System.Linq
{
/// <summary>
/// Class to hold extension methods to Linq.
/// </summary>
public static class LinqExtensions
{
/// <summary>
/// Changes all elements of IEnumerable by the change function
/// </summary>
/// <param name = "enumerable">The enumerable where you want to change stuff</param>
/// <param name = "change">The way you want to change the stuff</param>
/// <returns>An IEnumerable with all changes applied</returns>
public static IEnumerable<T> Change<T>(this IEnumerable<T> enumerable, Func<T, T> change )
{
ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
ArgumentCheck.IsNullorWhiteSpace(change, "change");
foreach (var item in enumerable)
{
yield return change(item);
}
}
/// <summary>
/// Changes all elements of IEnumerable by the change function, that fullfill the where function
/// </summary>
/// <param name = "enumerable">The enumerable where you want to change stuff</param>
/// <param name = "change">The way you want to change the stuff</param>
/// <param name = "where">The function to check where changes should be made</param>
/// <returns>
/// An IEnumerable with all changes applied
/// </returns>
public static IEnumerable<T> ChangeWhere<T>(this IEnumerable<T> enumerable,
Func<T, T> change,
Func<T, bool> @where)
{
ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
ArgumentCheck.IsNullorWhiteSpace(change, "change");
ArgumentCheck.IsNullorWhiteSpace(@where, "where");
foreach (var item in enumerable)
{
if (@where(item))
{
yield return change(item);
}
else
{
yield return item;
}
}
}
/// <summary>
/// Changes all elements of IEnumerable by the change function that do not fullfill the except function
/// </summary>
/// <param name = "enumerable">The enumerable where you want to change stuff</param>
/// <param name = "change">The way you want to change the stuff</param>
/// <param name = "where">The function to check where changes should not be made</param>
/// <returns>
/// An IEnumerable with all changes applied
/// </returns>
public static IEnumerable<T> ChangeExcept<T>(this IEnumerable<T> enumerable,
Func<T, T> change,
Func<T, bool> @where)
{
ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
ArgumentCheck.IsNullorWhiteSpace(change, "change");
ArgumentCheck.IsNullorWhiteSpace(@where, "where");
foreach (var item in enumerable)
{
if (!@where(item))
{
yield return change(item);
}
else
{
yield return item;
}
}
}
/// <summary>
/// Update all elements of IEnumerable by the update function (only works with reference types)
/// </summary>
/// <param name = "enumerable">The enumerable where you want to change stuff</param>
/// <param name = "update">The way you want to change the stuff</param>
/// <returns>
/// The same enumerable you passed in
/// </returns>
public static IEnumerable<T> Update<T>(this IEnumerable<T> enumerable,
Action<T> update) where T : class
{
ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
ArgumentCheck.IsNullorWhiteSpace(update, "update");
foreach (var item in enumerable)
{
update(item);
}
return enumerable;
}
/// <summary>
/// Update all elements of IEnumerable by the update function (only works with reference types)
/// where the where function returns true
/// </summary>
/// <param name = "enumerable">The enumerable where you want to change stuff</param>
/// <param name = "update">The way you want to change the stuff</param>
/// <param name = "where">The function to check where updates should be made</param>
/// <returns>
/// The same enumerable you passed in
/// </returns>
public static IEnumerable<T> UpdateWhere<T>(this IEnumerable<T> enumerable,
Action<T> update, Func<T, bool> where) where T : class
{
ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
ArgumentCheck.IsNullorWhiteSpace(update, "update");
foreach (var item in enumerable)
{
if (where(item))
{
update(item);
}
}
return enumerable;
}
/// <summary>
/// Update all elements of IEnumerable by the update function (only works with reference types)
/// Except the elements from the where function
/// </summary>
/// <param name = "enumerable">The enumerable where you want to change stuff</param>
/// <param name = "update">The way you want to change the stuff</param>
/// <param name = "where">The function to check where changes should not be made</param>
/// <returns>
/// The same enumerable you passed in
/// </returns>
public static IEnumerable<T> UpdateExcept<T>(this IEnumerable<T> enumerable,
Action<T> update, Func<T, bool> where) where T : class
{
ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
ArgumentCheck.IsNullorWhiteSpace(update, "update");
foreach (var item in enumerable)
{
if (!where(item))
{
update(item);
}
}
return enumerable;
}
}
}
Я использую это так:
List<int> exampleList = new List<int>()
{
1, 2 , 3
};
//2 , 3 , 4
var updated1 = exampleList.Change(x => x + 1);
//10, 2, 3
var updated2 = exampleList
.ChangeWhere( changeItem => changeItem * 10, // change you want to make
conditionItem => conditionItem < 2); // where you want to make the change
//1, 0, 0
var updated3 = exampleList
.ChangeExcept(changeItem => 0, //Change elements to 0
conditionItem => conditionItem == 1); //everywhere but where element is 1
Для справки проверка аргумента:
/// <summary>
/// Class for doing argument checks
/// </summary>
public static class ArgumentCheck
{
/// <summary>
/// Checks if a value is string or any other object if it is string
/// it checks for nullorwhitespace otherwhise it checks for null only
/// </summary>
/// <typeparam name = "T">Type of the item you want to check</typeparam>
/// <param name = "item">The item you want to check</param>
/// <param name = "nameOfTheArgument">Name of the argument</param>
public static void IsNullorWhiteSpace<T>(T item, string nameOfTheArgument = "")
{
Type type = typeof(T);
if (type == typeof(string) ||
type == typeof(String))
{
if (string.IsNullOrWhiteSpace(item as string))
{
throw new ArgumentException(nameOfTheArgument + " is null or Whitespace");
}
}
else
{
if (item == null)
{
throw new ArgumentException(nameOfTheArgument + " is null");
}
}
}
}
Хотя вы специально просили решение LINQ, и этот вопрос довольно старый, я публикую решение, не связанное с LINQ. Это потому, что LINQ (=
интегрированный язык запрос) предназначен для использования для запросов к коллекциям. Все LINQ-методы не изменяют базовую коллекцию, они просто возвращаться создают новую (или, точнее, итератор для новой коллекции). Таким образом, что бы вы ни делали, например с Select не влияет на базовую коллекцию, вы просто получаете новую.
Конечно, вы мог делаете это с ForEach (кстати, это не LINQ, а расширение на List<T>). Но этот буквально все равно использует foreach, но с лямбда-выражением. Помимо этого каждый метод LINQ выполняет внутреннюю итерацию вашей коллекции, например. используя foreach или for, однако он просто скрывает это от клиента. Я не считаю это более удобным для чтения и сопровождения (подумайте о редактировании кода при отладке метода, содержащего лямбда-выражения).
При этом не следует использовать элементы LINQ to модифицировать в вашей коллекции. Лучший способ - это решение, которое вы уже указали в своем вопросе. С помощью классического цикла вы можете легко перебирать свою коллекцию и обновлять ее элементы. На самом деле, все решения, основанные на List.ForEach, ничем не отличаются, но с моей точки зрения их гораздо труднее читать.
Поэтому вам не следует использовать LINQ в тех случаях, когда вы хотите Обновить элементов вашей коллекции.
Не по теме: я согласен, и есть оооочень много случаев злоупотребления LINQ, примеров людей, запрашивающих «высокопроизводительные цепочки LINQ», чтобы сделать то, что можно было бы выполнить с помощью одного цикла, и т. д. Я благодарен, что НЕ использование LINQ - это слишком укоренился во мне, и обычно не использую его. Я вижу людей, использующих цепочки LINQ для выполнения одного действия, не понимая, что почти каждый раз, когда используется команда LINQ, вы создаете еще один цикл for «под капотом». Я считаю, что создание менее подробных способов выполнения простых задач - это синтаксический сахар, а не замена стандартному кодированию.
Предположим, у нас есть данные, как показано ниже,
var items = new List<string>({"123", "456", "789"});
// Like 123 value get updated to 123ABC ..
и если мы хотим изменить список и заменить существующие значения списка на измененные значения, то сначала создайте новый пустой список, а затем прокрутите список данных, вызвав метод модификации для каждого элемента списка,
var modifiedItemsList = new List<string>();
items.ForEach(i => {
var modifiedValue = ModifyingMethod(i);
modifiedItemsList.Add(items.AsEnumerable().Where(w => w == i).Select(x => modifiedValue).ToList().FirstOrDefault()?.ToString())
});
// assign back the modified list
items = modifiedItemsList;
Зачем вам делать что-то, что может работать за O (n), выполняется за O (n ^ 2) или хуже? IM не знает, как работают особенности linq, но я вижу, что это как минимум n ^ 2 решение проблемы п.
Интересный вопрос. Лично я предпочитаю, как это у вас выше - гораздо яснее, что происходит!