通过复制列表中的反射设置属性更新原始列表

时间:2015-12-01 21:03:49

标签: c# .net reflection properties setvalue

我在C#代码中遇到问题,我确定它与我使用反射的方式有关,但我不确定如何修复它。

据我所知,如果我有:

List1 = List<MyClass>

并使用类似于

的语法
List2 = new List<MyClass>(List1);

然后List2应该是List1的副本,对其进行的任何更新都不应反映在原始列表中。

在这种情况下,请考虑以下测试代码:

public class Fake
{
    public string MyVal { get; set; }
}

public List<Fake> List1;
public List<Fake> List2;

public void UpdateClassTest()
{
    List1 = new List<Fake>() {new Fake() { MyVal = "hello" } };

    List2 = new List<Fake>(List1);
    string propName;

    System.Type type = typeof(Fake);
    foreach (System.Reflection.PropertyInfo pi in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
    {
        propName = pi.Name;
        List2.ForEach(f => pi.SetValue(f, "Good Bye"));
    }
}

当我运行此 List1[0]List2[0]更新为“再见”时,我认为List1不会受到更改的影响我正在List2

我做错了什么或者不在这里理解?

2 个答案:

答案 0 :(得分:3)

新列表(列出其他)不做深层复制。当您修改[0]处的项目时,它正在修改原始对象,该对象存在于两个列表中。

See this other question about implementing ICloneable.

答案 1 :(得分:2)

复制列表意味着列表是不同的对象。列表中包含的元素仍然相同。例如:

List1 = new List<Fake>() {new Fake { MyVal = "hello" } };
List2 = new List<Fake>(List1);

List2.Add(new Fake { MyVal = "hey" });
Console.WriteLine(List1.Length); // 1
Console.WriteLine(List2.Length); // 2

List2[0].MyVal = "hi";
Console.WriteLine(List1[0].MyVal) // hi