ここでは、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オブジェクトを変更することはできません。それは不変です。そのメソッド (この場合はプラス演算子とマイナス演算子) を呼び出すと、まったく新しいオブジェクトが返されます。慣例により、値型は処理が難しい場合が多いため、やむを得ない理由がない限り変更可能であってはなりません。参照型は不変または可変のいずれかです。どちらも重大な問題はありません (一般的な場合)。