19

C# で 2 つの変数が異なる DateTime オブジェクトを指しているのはなぜですか?

DateTime a1 = DateTime.Now;
DateTime a2 = a1;

a1 = a1 + TimeSpan.FromMinutes(15);
a2 = a2 - TimeSpan.FromMinutes(16);

a2 が実際には a1 とは異なる新しいオブジェクトを指していることに気付きました。

しかし、それ以外の場合。クラス Person があり、age = 1; とします。

Person a1 = new Person();
a2 = a1;
a2 = Person.Age = 2;

Person Case では、a1 と a2 は同じオブジェクトを指しています。私はここで本当に混乱しています、誰か説明できますか?

4

4 に答える 4

40

DateTime値型 - 構造体です。

値型で、次のようなことをすると:

DateTime a2 = a1;

a2の値のコピーを取得しますa1。これは、同じメモリ位置への同じ参照ではなく、完全な別のコピーです。

一方、Person参照型 - クラスです。

あなたがするとき:

Person p2 = p1;

参照型の場合、指す参照はp2指すものと同じp1です。したがって、一方の変更は両方の変更です。

MSDNの値の型と参照型を参照してください。

于 2012-10-09T19:26:52.440 に答える
8

他の人がすでに指摘しているようDateTimeに、クラスではなく構造体であるため、値型です。構造体の表示に使用するテキストの色を変更すると、Visual Studio エディターでこれを視覚化できます。メニューTools>でダイアログを開き、 >Optionsに移動します。EnvironmentFonts and Colors

ここに画像の説明を入力

デリゲート、列挙型、インターフェイス、および構造体 (値の型) の色を変更すると便利です。

ここに画像の説明を入力

Visual Studio 2019 では、定数やパラメーターなどのユーザー メンバーの外観を変更することもできます。

于 2012-10-09T20:11:21.380 に答える
4

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

于 2012-10-09T19:56:30.307 に答える
3

ここでの違いは、DateTime が値型であり、Person が参照型 (クラス) であると想定していることです。

値型の変数割り当ての場合、実際にはメモリの内容をある場所から別の場所にコピーしています。

ただし、参照型の場合は、まだ同じメモリを指しています。

于 2012-10-09T19:26:26.327 に答える