C# 在C中生成列表的新实例#

C# 在C中生成列表的新实例#,c#,list,reference,clone,C#,List,Reference,Clone,我在使用C#时遇到了一个问题,如果我初始化某个列表,比如说list exampleList使用另一个预先存在的列表,比如说toModify如下:list exampleList=new list(toModify)。当我稍后修改toModify列表时,新创建的列表也会修改自身。如果它通过引用传递值,exampleList的值不应该保持不变,因为它是从另一个生成的吗 TLDR:当我更改第二个列表时,我使用另一个列表(第二个列表)初始化的列表的值会更改。我来自Java背景,不明白为什么会发生这种情况

我在使用C#时遇到了一个问题,如果我初始化某个列表,比如说
list exampleList
使用另一个预先存在的列表,比如说toModify如下:
list exampleList=new list(toModify)
。当我稍后修改toModify列表时,新创建的列表也会修改自身。如果它通过引用传递值,exampleList的值不应该保持不变,因为它是从另一个生成的吗

TLDR:当我更改第二个列表时,我使用另一个列表(第二个列表)初始化的列表的值会更改。我来自Java背景,不明白为什么会发生这种情况。我会一直使用克隆吗?

是的

您正在创建一个新列表,其中包含与旧列表相同的项目。如果清除第一个列表,则第二个列表中的项目将保留

但是,如果更改第一个列表中某个项目的属性,则该属性与第二个列表中的对象相同

因此,两个列表都引用了内存中相同的项。编写
list1[0].SomeProperty=1
时,您正在使用与
list2
中相同的对象引用对其进行更改,因此更改将反映在第二个列表中

有关如何克隆列表并生成项目的新引用,请选中此选项。

在下一行:

List<T> exampleList = new List<T>(toModify)

让我们用这个例子:

        List<A> firstList = new List<A>()
        {
            new A() { Id = 3 },
            new A() { Id = 5 }
        };

        List<A> secondList = new List<A>(firstList);

        secondList[1].Id = 999;

        Console.WriteLine(firstList[1].Id);

输出:5

C#的行为在这方面与Java的行为完全相同。你能解释一下你说“修改”名单是什么意思吗?也许可以提供一个简单的代码示例来显示您看到的行为?为什么他们不为接口列表创建一个函数,以便您可以复制它而不发生这种情况?换言之,更改内存引用创建一个新的内存引用,而不必创建克隆方法来执行此任务?@TiPiTo复制对象比您想象的更复杂。您可能拥有子对象和复杂特性的层次结构。使用C#中的Google“Deep Copy”。使用Deep Copy“克隆”对象不是一种非常低效的方式吗,因为它会遍历每个索引,而不仅仅是复制内存块?@TiPiTo是的,这就是为什么看到它被复制是一个危险信号;通常情况下,您会以一种不必要的方式设计代码。既然您提到了这一点,我可以做些什么来避免不得不处理这一问题?是否存在一种模式或其他通常在预期出现此问题的情况下实现的方法?如何在不使用克隆方法的情况下使引用类型通过值传递?如何使对象将引用复制到另一个内存块并仅修改该块?Hmmmm,这行“对象复制引用到另一个内存块”是什么意思?我不只是创建新对象点或引用第一个对象,如何创建该引用的精确副本并将其放置在另一个位置,以便在修改第二个对象时不修改第一个对象?好吧,您可以阅读一些关于引用类型以及它们如何在C#中工作的内容。引用只指向对象,我们称之为A,当你想创建另一个具有相同值的对象B,但当A为时,它不会被修改,你需要创建一个新对象和对它的新引用。正如你在C中看到的,对象的行为类似于现实生活中的对象,如果您修改了对象,并且它在一些3个列表中被引用,那么所有这些列表都会被修改,因为这些列表只包含对它的引用,而不是对象本身。
        List<A> firstList = new List<A>()
        {
            new A() { Id = 3 },
            new A() { Id = 5 }
        };

        List<A> secondList = new List<A>(firstList);

        secondList[1].Id = 999;

        Console.WriteLine(firstList[1].Id);
        List<A> firstList = new List<A>()
        {
            new A() { Id = 3 },
            new A() { Id = 5 }
        };

        List<A> secondList = firstList.Select(el => new A() { Id = el.Id }).ToList();

        secondList[1].Id = 999;

        Console.WriteLine(firstList[1].Id);