Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 复制词典的意外结果_C#_.net_Dictionary - Fatal编程技术网

C# 复制词典的意外结果

C# 复制词典的意外结果,c#,.net,dictionary,C#,.net,Dictionary,这与我认为我对抄写字典的理解背道而驰。比如,我有以下代码: public class MyClass { public string str1; public MyClass(string s) { str1 = s; } } Dictionary<string, MyClass> dic1 = new Dictionary<string, MyClass>(); dic1.Add("0", new MyClass("h

这与我认为我对抄写字典的理解背道而驰。比如,我有以下代码:

public class MyClass
{
    public string str1;

    public MyClass(string s)
    {
        str1 = s;
    }
}

Dictionary<string, MyClass> dic1 = new Dictionary<string, MyClass>();
dic1.Add("0", new MyClass("hello"));

//Make 'dic2' as a copy of 'dic1'
Dictionary<string, MyClass> dic2 = new Dictionary<string, MyClass>(dic1);

//Alter 'dic1'
dic1.ElementAt(0).Value.str1 += "!!!";

//I was expecting dic2 not to be altered, but IT IS!
Debug.Assert(dic2["0"].str1.Equals(dic1["0"].str1, StringComparison.Ordinal) == false);     //Result is true for equality
公共类MyClass
{
公共字符串str1;
公共MyClass(字符串s)
{
str1=s;
}
}
字典dic1=新字典();
dic1.添加(“0”,新MyClass(“hello”);
//将“dic2”作为“dic1”的副本
字典dic2=新字典(dic1);
//更改“dic1”
dic1.ElementAt(0).Value.str1+=“!!!”;
//我原以为dic2不会被修改,但事实就是如此!
Assert(dic2[“0”].str1.Equals(dic1[“0”].str1,StringComparison.Ordinal)==false)//结果是平等的
我原以为更改复制的词典不会更改原始词典,但我的代码并非如此


我做错了什么?

正如科拉克所说,你做了一个肤浅的复制。您正在复制对内存中对象的引用,而不是对象本身。现在,对于每个键,有两个对一个对象的引用


您需要的是深度复制,请参见此处:

谷歌提示:
浅层复制
深度复制
。您复制的是引用,而不是实际的对象。您可以阅读Jon Skeets的文章,这篇文章也解释了引用。@默认值:我只是希望它有更好的文档记录。我在搜索“C#copy dictionary”后开始使用这种方法,认为我的整个字典都被复制了。好吧,我不确定你读过什么:)对我来说,引用被复制感觉很自然,但我来自一个编程背景,而你来自另一个编程背景。也许那些写你读过的文档的人认为读者知道引用是作为引用复制的。谢谢。虽然有点混乱。显然,字典可以嵌套,所以如果我在父字典上执行“浅复制”,而“嵌套”字典执行“深度复制”,该怎么办?字典只是将键映射到值。这些值是引用而不是对象,这只是C#的工作方式。值可以是结构,在这种情况下,它们的行为可能会有所不同(虽然已经多年了,我有点模糊)。至于嵌套字典,我认为你必须实现自己的复制方法。是的,我必须自己做,因为您链接到的代码示例在我的案例中不起作用,因为我自己的类是值。很抱歉,该实现不适用于您。但是,如果您正在实现自己的类并以这种方式使用它们,那么您就有责任实现克隆功能。祝你好运