ここでは、2 つの別個の概念が機能しています。1 つ目は、[おそらく] 参照型 (クラス) であるDateTime
一方で、値型 (構造体とも呼ばれます) です。Person
このため、次の場合:
DateTime date1 = DateTime.Now;
DateTime date2 = date1;
date2
値がコピーされるため、2 つの変数が同じオブジェクトを参照することはありません。
クラスを使用すると、次のようになります。
Person p1 = new Person();
Person p2 = p1;
p1
は実際には含まれておらず、 person へPerson
の参照が含まれているだけです。次に、その参照が (値によって) にコピーされます。その参照をコピーすると、両方の変数が同じオブジェクトを「指し示す」または「参照する」ようになります。p2
次に、可変性の問題があります。 Person
、この場合、可変型です。変えられるということですね。一方、不変型は一度構築すると変更できません。
この線:
p2.Age = 2;
p2
参照するオブジェクトを実際に変更してp2
おり、p1
両方とも同じオブジェクトを参照しているp1.Age
ため2
、そのコード行の後にあります。
Person
ここで、デモンストレーションのために、不変クラスを作成しましょう。
public class Person
{
private int _age;
public Person(int someAge)
{
_age = someAge;
}
public int Age
{
get { return _age; }
}
public Person Grow()
{
return new Person(_age + 1);
}
}
次のようにすると:
Person p1 = new Person(1);
Person p2 = p1;
p2 = p2.Grow();
2 行目は以前とまったく同じことを行っており、両方が同じオブジェクトを指していることを確認していますが、3 行目は異なっています。その人物を変更 (またはミューテーション) して 1 歳年上にするのではなく、このGrow
メソッドは1 歳年上の人物を表す新しいPerson
オブジェクトを返します。p2
これを行った後p1
、同じオブジェクトを参照しなくなります。p2
メソッドが作成したばかりの新しいオブジェクトを参照するオブジェクトを変更しGrow
ました。
この 2 番目の例は、 で起こっていることにかなり似ていDateTime
ます。DateTime
オブジェクトを変更することはできません。それは不変です。そのメソッド (この場合はプラス演算子とマイナス演算子) を呼び出すと、まったく新しいオブジェクトが返されます。慣例により、値型は処理が難しい場合が多いため、やむを得ない理由がない限り変更可能であってはなりません。参照型は不変または可変のいずれかです。どちらも重大な問題はありません (一般的な場合)。