質問

だから私は今日、C#の変数に割り当てるために構造体とクラスが異なる行動をとることを知りました。変数に構造体を割り当てるとき、変数はその構造体のコピーを保存し、クラスを割り当てるときに理解してください。変数に対して、変数はそのクラスインスタンスへの参照を保存します。

この場合、DAD2にはDAD1のコピーが含まれているので、DAD2に私がすることはDAD1に影響しないでください。息子をdad2に追加すると、同じ息子をdad1に追加するとは思われません。

public struct Dad {
        public string name;
        public List <Son> sons;

        public struct Son {
            public string name;

            public Son (string n) {
                name = n;
            }
        }
    }

    static void Main (string [] args) {
        Dad dad1 = new Dad ();
        dad1.name = "Bob";
        dad1.sons = new List <Dad.Son> {new Dad.Son ("A")};

        Dad dad2 = dad1;
        Debug.WriteLine (dad2.Equals (dad1) + " " + dad1.sons.Count () + " " + dad2.sons.Count ());
        //true 1 1
        dad2.sons.Add ( new Dad.Son ("B"));
        Debug.WriteLine (dad2.Equals (dad1) + " " + dad1.sons.Count () + " " + dad2.sons.Count ());
        //true 2 2
    }
役に立ちましたか?

解決

はい、それは構造体内の値のコピーを作成します - および構造内の内部には、リファレンスがコピーされるようにリストへの参照があります - それは「浅いコピー」です...リストが新しいものにコピーされた場合オブジェクトこれは「ディープコピー」になります... struct割り当ては、各メンバーのコピーセマンティクスに依存する「コピー」セマンティクスを使用します...参照 http://msdn.microsoft.com/en-us/library/saxz13w4.aspx

他のヒント

クラスタイプの変数とフィールドは「インスタンスID」を保持していると考えてください。そうすれば、すべてが明確になります。タイプリストのstructフィールド「foo」に「インスタンスID#95341」の値があるとします。構造体をコピーすると、フィールド「Foo」が「インスタンスID#95341」も保持している別の構造体が生成されます。そのような構造体にfoo.addを呼び出すと、リストに要素が追加されます byで言及されています 「インスタンスID#95341」。他のそのような構造体のfoo.countのクエリは、「インスタンスID#95341」で言及されたリストからカウントを取得します。これは当然同じリストになります。

私はこれに答えています

それで、DAD2に私がすることはDAD1に影響しないべきではないでしょうか?」

コードを使用すると、の変更があります

public List <Son> sons;

両方のコピー(DAD1とDAD2)に見られます。ただし、変更はありません

public string name;

変更されたオブジェクトでのみ表示されます

例 - dad2の名前のみを変更し、dad1の名前ではありません

Dad dad1 = new Dad();
dad1.name = "Bob";
dad1.sons = new List<Dad.Son> { new Dad.Son("A") };

Dad dad2 = dad1;
Console.WriteLine(dad2.Equals(dad1) + " " + dad1.sons.Count() + " " + dad2.sons.Count());
//true 1 1
dad2.sons.Add(new Dad.Son("B"));
Console.WriteLine(dad2.Equals(dad1) + " " + dad1.sons.Count() + " " + dad2.sons.Count());
//true 2 2

dad2.name = "Tom";
Console.WriteLine(dad2.Equals(dad1) + " " + dad1.sons.Count() + " " + dad2.sons.Count());
//False 2 2
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top