C#の値渡しと参照渡し
MemberwiseClone メソッドを使用することでインスタンスのコピーを作成することができる。
「自分自身のなかに持っているデータをそっくり丸ごとnewしたインスタンスにコピーしてやる、という機能を持つ。」
オブジェクト全体の浅いコピーを作成する機能を持ったものである。
「浅いコピー」とは、そのオブジェクトだけの複製を作ることを意味する。
逆に深いコピーとは、オブジェクトから参照されるオブジェクトも含めたコピーを作成すること。
Structsは値型である為、newの必要がなく、代入は値渡しになる。
クラスは参照型である為、newが必要で、代入は参照渡しになる。
object型はすべてのクラスのスーパークラス、参照型。
object testObject1,testObject2; testObject1 = 123;
と記述するとボクシング処理が自動的に挿入され、そのインスタンスが自動で作成される。
「int型整数の123という値をobject型の変数に入れようとしている。
このような値型を参照型として使おうとする状況があると、
コンパイラはボクシング処理を自動的に挿入する。
その結果、整数型の変数を包み込むクラスが見えないところで準備され、
そのインスタンスが自動的に作成され、ここでは123という値が書き込まれる。」
amespace ConsoleApplication9 using System; public class TestClass : ICloneable { public int n; public object Clone() { return MemberwiseClone(); } } public struct TestStructs { public int n; } public class Class1 { public static int Main(string[] args) { int testInt1,testInt2; testInt1 = 123; testInt2 = testInt1; testInt1 = 456; Console.WriteLine( "Answer1 testInt1={0}, testInt2={1}", testInt1, testInt2 ); TestClass testClass1,testClass2; testClass1 = new TestClass(); testClass2 = new TestClass(); testClass1.n = 123; testClass2.n = testClass1.n; testClass1.n = 456; Console.WriteLine( "Answer2 testClass1.n={0}, testClass2.n={1}", testClass1.n, testClass2.n ); TestClass testClass1a,testClass2a; testClass1a = new TestClass(); testClass1a.n = 123; testClass2a = testClass1a; testClass1a.n = 456; Console.WriteLine( "Answer3 testClass1a.n={0}, testClass2a.n={1}", testClass1a.n, testClass2a.n ); TestClass testClass1b,testClass2b; testClass1b = new TestClass(); testClass1b.n = 123; testClass2b = (TestClass)testClass1b.Clone(); testClass1b.n = 456; Console.WriteLine( "Answer4 testClass1b.n={0}, testClass2b.n={1}", testClass1b.n, testClass2b.n ); TestStructs testStructs1,testStructs2; testStructs1.n = 123; testStructs2 = testStructs1; testStructs1.n = 456; Console.WriteLine( "Answer5 testStructs1.n={0}, testStructs2.n={1}", testStructs1.n, testStructs2.n ); object testObject1,testObject2; testObject1 = 123; testObject2 = testObject1; testObject1 = 456; Console.WriteLine( "Answer6 testObject1={0}, testObject2={1}", testObject1, testObject2 ); return 0; } }