Подтвердить что ты не робот

С# как назначить List <T> без ссылки?

Например

List<string> name_list1 = new List<string>();
List<string> name_list2 = new List<string>();

далее в коде:

name_list1.Add("McDonald");
name_list1.Add("Harveys");
name_list1.Add("Wendys");

name_list2 = name_list1; // I make a copy of namelist1 to namelist2

Итак, с этой точки я хотел бы продолжать добавлять элемент или вносить изменения в name_list2, не затрагивая name_list1. Как это сделать?

4b9b3361

Ответ 1

name_list2 = new List<string>(name_list1);

Это приведет к клонированию списка.

Ответ 2

name_list2 = new List<string>(name_list1); // Clone list into a different object

В этот момент два списка представляют собой разные объекты. Вы можете добавлять элементы в список2, не затрагивая list1

Ответ 3

Проблема в назначении. До назначения name_list2 = name_list1; у вас есть два разных объекта List в куче, на которые указывают переменные name_list1 и name_list2. Вы заполняете name_list1, что хорошо. Но назначение говорит: "сделать так, чтобы name_list2 указывал на тот же объект в куче, что и name_list1 ". Список, на который name_list2 больше недоступен и будет собираться мусором. Что вы действительно хотите, это скопировать содержимое name_list1 в name_list2. Вы можете сделать это с List.AddRange. Обратите внимание, что это приведет к "мелкой" копии, что хорошо для приведенного вами примера, где содержимое списка является строкой, но может не соответствовать желаемому, когда члены списка являются более сложными объектами. Все зависит от ваших потребностей.

Ответ 4

Другие параметры: Глубокое клонирование

public static T DeepCopy<T>(T item)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            MemoryStream stream = new MemoryStream();
            formatter.Serialize(stream, item);
            stream.Seek(0, SeekOrigin.Begin);
            T result = (T)formatter.Deserialize(stream);
            stream.Close();
            return result;
        }

так,

вы можете использовать:

name_list2 = DeepCopy<List<string>>(name_list1);

ИЛИ

name_list2 = DeepCopy(name_list1); 

также будет работать.

Ответ 5

Вот альтернативное решение:

    List<string> name_list1 = new List<string>();
    List<string> name_list2 = new List<string>();

    name_list1.Add("McDonald");
    name_list1.Add("Harveys");
    name_list1.Add("Wendys");

    name_list2.AddRange(name_list1.ToArray());

Метод ToArray() копирует 'name_list1' в новый массив, который мы затем добавляем в name_list2 с помощью метода AddRange().

Ответ 6

Мне нравится linq для этого...

Если элементы списка являются примитивами или структурами, то...

L2 = L1.ToList()

Если элементы списка являются классами, то...

L2 = L1.Select(x => x.Copy()).ToList();

Где Copy может быть просто экспоненциальной экспозицией MemberWiseClone, или это может быть некоторая реализация глубокой копии.

Ответ 7

Я предпочитаю метод преобразователя Json для сериализации и десериализации, так что вам не нужно отмечать классы для сериализации, особенно у вас есть множество дочерних классов.

https://www.newtonsoft.com/json/help/html/SerializingJSON.htm

Ответ 8

Для Примитивных Типов вы можете сделать это:

List<string> CopyList = new List<string>(OriginalList);

Для не примитивных/пользовательских типов вы можете сделать это:

List<Person> CopyList = new List<Person>();
foreach(var item in OriginalList)
{
    CopyList.Add(new Person { 
            Name = item.Name,
            Address = item.Address
    });
}

Ответ 9

Для примитивных типов:
List ClonedList = новый список (OriginalList);

Для не примитивных/пользовательских типов:
Нам необходимо выполнить глубокое копирование: глубокое копирование используется для создания полной глубокой копии внутренних ссылочных типов, для этого нам нужно настроить объект, возвращаемый MemberwiseClone().

Step1- В вашем классе наследуют от ICloneable:
открытый класс MyClass: ICloneable

Step2- Реализация метода

public MyClass Clone()
{
  MyClass MyClassObj =new MyClass();
  MyClassObj.Property1 = this.Property1;
  .
  .
  MyClassObj.Property_N = this.Property_N;
  return MyClass;
}

Step3- теперь клонирую ваш список

List<MyClass> MyClassClone = new List<MyClass>(); 
for(i=0; i<Count; i++)
  {
      MyClassClone.Add(OriginalClaaObj[i].Clone());
  }

Это сделает глубокую копию каждого предмета объекта.

Ответ 10

Если оба списка одного и того же сложного типа, вы можете сделать что-то вроде ниже: -

SomeClass List2 = новый список(); List1.ForEach(u => List2.Add(u));

Что я делаю, так это перебираю каждый элемент List1 и продолжаю добавлять его в List2. Я считаю, что это самый короткий способ сделать это.

Ответ 11

Ни одно из вышеперечисленных решений не помогло мне при использовании списков объектов класса.

Это может быть использовано для копирования любого объекта в другой объект с именами общих свойств.

public static void ObjectToObject(object source, object destination)
{
  // Purpose : Use reflection to set property values of objects that share the same property names.
  Type s = source.GetType();
  Type d = destination.GetType();

  const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;

  var objSourceProperties = s.GetProperties(flags);
  var objDestinationProperties = d.GetProperties(flags);

  var propertyNames = objSourceProperties
  .Select(c => c.Name)
  .ToList();

  foreach (var properties in objDestinationProperties.Where(properties => propertyNames.Contains(properties.Name)))
  {

    try
    {
      PropertyInfo piSource = source.GetType().GetProperty(properties.Name);

      properties.SetValue(destination, piSource.GetValue(source, null), null);
    }
    catch (Exception ex)
    {
      throw;
    }

  }
}


public static List<T> CopyList<T>(this List<T> lst)
{
  List<T> lstCopy = new List<T>();

  foreach (var item in lst)
  {
    var instanceOfT = Activator.CreateInstance<T>();
    ObjectToObject(item, instanceOfT);
    lstCopy.Add(instanceOfT);
  }
  return lstCopy;
}

Для списков используйте это: list2 = list1.CopyList();