2016-11-17 2 views
-2

Обычно функция добавления, где, если я даю один список и элемент, возвращает полностью новый список с добавленным элементом. Я не спрашиваю, как это сделать, я хочу знать, есть ли эффективный способ сделать это встроенным в источник .Net. Очевидно, я мог бы просто сделать что-то подобное;В C# существует ли способ по умолчанию для создания нового списка с добавленным элементом без изменения исходного списка?

List<string> newList = new List<string>(); 
newList.AddRange(oldList); 
newList.Add(newElem); 

Но есть ли лучший способ?

+0

ImmutableList специально для этого. – Alan

ответ

0

Попробуйте это:

List<string> newList = new List<string>(oldList) { newElem }; 
+0

Я думаю, что это лучшее решение для меня, так как оно не требует установки каких-либо пакетов nuget. – Maurdekye

1

Да, есть неизменные коллекции. https://dotnetcodr.com/2015/09/23/using-immutable-collections-for-thread-safe-read-only-operations-in-net/

https://blogs.msdn.microsoft.com/dotnet/2013/09/25/immutable-collections-ready-for-prime-time/

Доступно через NuGet пакет "System.Collections.Immutable".

С сайта:

Что неизменны коллекции? Со временем .NET Framework имеет , добавив множество функций, которые сделали параллельное программирование намного проще. Это началось с введения пула потоков, получившего гораздо больше с моделью на основе задач и параллельной библиотекой задач (TPL), и было еще больше улучшено добавлением асинхронных и ожидающих ключевых слов языка. При создании и запуске одновременно проще, чем когда-либо, одна из основных проблем все еще существует: измененное общее состояние. Чтение из нескольких потоков, как правило, очень легко, но как только состояние нужно обновить, оно становится намного сложнее, особенно в конструкциях, требующих блокировки. Альтернативой блокировке является использование неизменяемого состояния. Неизменяемые структуры данных: гарантированно никогда не меняются и могут свободно передаваться между различными темами, не беспокоясь о том, чтобы наступать на чужой пальцев.

Как и другие, это можно сделать без неизменяемых коллекций. Если вы работаете только над проектом, или если вы уверены, что имеете контроль над источником, то это может сделать. Но ошибку легко сделать, особенно когда в списки есть много изменений. Используя Immutable Collections, вам не нужно беспокоиться или меньше беспокоиться об этих ошибках.

+0

Хорошо, спасибо; Я попробую это. – Maurdekye

+4

Ответы только на ссылку не нужны для SO, потому что ссылки могут сломать линию. В дополнение к ссылкам, пожалуйста, также предоставьте соответствующую информацию из ссылки, чтобы ответ мог стоять сам по себе, даже если ссылки не работают. –

+0

Они, кажется, не являются по умолчанию в библиотеках .Net, я не могу их импортировать. – Maurdekye

0

Да, с помощью LINQ.

var list = new []{1, 3, 4}.Concat(new []{6}).ToList() // list now contains 1,3,4,6 

Вы также можете определить перегрузку Concat, которая принимает один элемент, так что вам не нужно, чтобы создать список с одним элементом.

+1

или 'Enumerable.Repeat (6,1)', чтобы избежать этого массива. – juharr

0

Для того, чтобы избежать изменения размера, включая создание нового внутреннего массива и операцию копирования массива, я хотел бы создать новый список, указав свой новый начальный потенциал, но в остальном все-таки использовать свой подход:

List<string> newList = new List<string>(oldList.Count + 1); 
newList.AddRange(oldList); 
newList.Add(newElem); 

Совершенно иной подход заключается в том, чтобы заимствовать концепцию из функциональных языков, где используются связанные списки. Вместо создания копии списка и добавления одного элемента новые элементы добавляются перед списком, а ссылка на первый элемент возвращается как ссылка на оставшуюся часть списка.Список можно перечислить только с этого элемента до конца. Это потокобезопасность, поскольку нить никогда не видит вновь добавленные элементы.