如何分配 List<T>,而不是引用原始的 List<T>?

91
例如
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_list1的情况下继续向name_list2中添加元素或进行更改。我该怎么做?


这个解决方案适用于每个复杂对象的克隆。 - Kalpesh Dabhi
17个回答

1
对于基本类型:
List ClonedList = new list(OriginalList); 对于非基本类型/用户定义类型:
我们需要执行深拷贝: 深拷贝用于完全复制内部引用类型,为此我们需要配置由MemberwiseClone()返回的对象。
步骤1- 在您的类中继承ICloneable:
public class MyClass:ICloneable 步骤2- 实现方法
public MyClass Clone()
{
  MyClass MyClassObj =new MyClass();
  MyClassObj.Property1 = this.Property1;
  .
  .
  MyClassObj.Property_N = this.Property_N;
  return MyClass;
}

步骤3- 现在克隆您的列表
List<MyClass> MyClassClone = new List<MyClass>(); 
for(i=0; i<Count; i++)
  {
      MyClassClone.Add(OriginalClaaObj[i].Clone());
  }

这将对对象的每个项目进行深层复制。

1

虽然这可能会成为潜在的性能威胁解决方案,但它会优雅地逐个属性复制值。

using Newstonsoft.Json;

ClassA classA = new ClassA();
ClassA classACopyWithoutReference = JsonConvert.DeserializeObject<ClassA>(JsonConvert.SerializeObject(classA));

0

当使用类对象列表时,以上解决方案都不适用于我。

这可用于将任何对象复制到具有共享属性名称的另一个对象。

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();

请添加一些描述代码功能的内容,以便未来阅读答案的人可以理解您的解决方案。 - Adam B

0

这个解决方案适用于复杂对象(将T替换为你的类型名称):

list2 = list1.Concat(new List<T> { object }).ToList();

或者:

list2 = list1.ToArray().Append(object).ToList()

0
找到一个可行的答案花了我太长时间,所以我会发布对我有效的解决方案:
List<MyItem> L2 = L1.Select(x => x.Clone()).ToList();

但是你必须在你的类/对象 "MyItem" 中实现 Clone 方法。
public class MyItem
{
    public MyItem Clone()
    {
        return (MyItem)this.MemberwiseClone();
    }
}

0
如果两个列表都是相同的复杂类型,那么你可以像下面这样做:
SomeClass List2 = new List();
List1.ForEach(u => List2.Add(u));
我所做的是遍历List1的每个元素,并将其添加到List2中。 我相信这是最简洁的方法。

一个简单的测试表明这也是通过引用传递的。更改一个列表,另一个列表也会被更改。 - Matthew

-1

使用LINQ对我来说很有效...

lst1= lst2.ToList();

你确定这不是对原始列表的引用吗? - Ryanman
这样不行。它是对原始列表的引用。在一个列表中进行更改会反映在另一个列表中。 - Matthew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接