【问题标题】:Setting a Property via Reflection in a copied List updates original list在复制的列表中通过反射设置属性会更新原始列表
【发布时间】:2026-02-06 18:40:01
【问题描述】:

我的 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 不会受到我对 @ 所做的更改的影响987654329@.

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

【问题讨论】:

    标签: c# .net reflection properties setvalue


    【解决方案1】:

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

    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
    

    【讨论】:

    • 非常感谢。这很糟糕,但有道理!
    【解决方案2】:

    new List(List other) 不做深拷贝。当您修改 [0] 处的项目时,它正在修改两个列表中都存在的原始对象。

    See this other question about implementing ICloneable.

    【讨论】:

    • 谢谢!! - 这很糟糕,但有道理:)
    最近更新 更多