7

C# で新しいオブジェクト初期化子を使用してオブジェクトを初期化すると、クラス内のプロパティの 1 つを使用してさらにアクションを実行できず、その理由がわかりません。

私のコード例:

Person person = new Person { Name = "David", Age = "29" };

Person クラス内では、x は 0 (デフォルト) になります。

public Person()
{
  int x = Age; // x remains 0 - edit age should be Age. This was a typo
}

しかし、person.Age は 29 に等しいです。これは正常なことだと確信していますが、その理由を理解したいと思います。

4

6 に答える 6

21

コンストラクター'publicPerson()'の実行が終了すると、プロパティはNameとAgeに設定されます。

Person person = new Person { Name = "David", Age = "29" };

と同等です

Person tempPerson = new Person()
tempPerson.Name = "David";
tempPerson.Age = "29";
Person person = tempPerson;

したがって、コンストラクターでは、Ageはまだ29になりません。

(tempPersonは、この方法で構築された他のPersonインスタンスと衝突しない、コードに表示されない一意の変数名です。tempPersonは、マルチスレッドの問題を回避するために必要です。この使用により、新しいオブジェクトがコンストラクターが実行され、すべてのプロパティが初期化されるまで、他のスレッドで使用できます。)


コンストラクターでAgeプロパティを操作できるようにする場合は、年齢を引数として取るコンストラクターを作成することをお勧めします。

public Person(string name, int age)
{
   Name = name;
   Age = age;

   // Now do something with Age
   int x = Age;
   // ...
}
于 2009-02-17T22:05:56.630 に答える
9

重要な技術的詳細として、次のことに注意してください。

Person person = new Person { Name = "David", Age = "29" };

次と同等です。

Person <>0 = new Person(); // a local variable which is not visible within C#
<>0.Name = "David";
<>0.Age = "29";
Person person = <>0;

ただし、次とは同等ではありません:

Person person = new Person();
person.Name = "David";
person.Age = "29";
于 2009-02-17T22:14:10.340 に答える
6

コード行は次のものと同じです。

Person person = new Person() { Name = "David", Age = "29" };

これは次と同じです:

Person person = new Person();
person.Name = "David";
person.Age = "29";

ご覧のように; コンストラクターが実行されるとき、Ageはまだ設定されていません。

于 2009-02-17T22:06:42.667 に答える
4

技術的には、このコード:

Person person = new Person { Name = "David", Age = 29 };

は次のコードと同じです:

Person tmpPerson = new Person();
tmpPerson.Name = "David";
tmpPerson.Age = 29;
Person person = tmpPerson;

これは、他の人が投稿したものとはわずかに異なります。

Person person = new Person();
person.Name = "David";
person.Age = 29;

アプリケーションがマルチスレッドを使用している場合、この違いは非常に重要です。

于 2009-02-17T22:16:23.067 に答える
3

Ageオブジェクトのコンストラクタでアクセスしようとしているようです。オブジェクト初期化子の値は、コンストラクターが実行されるまで設定されません。

これを試して:

Person person = new Person { Name = "David", Age = 29 };
int x = person.Age;

コメントに応じて編集

コンストラクター自体でにアクセスする必要がある場合Ageは、必要なパラメーターを使用して明示的なコンストラクターを作成し、オブジェクト初期化構文の代わりにそれを使用する必要があります。例えば:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    public Person(string name, int age)
    {
        Name = name;
        Age = age;

        int x = Age;  // will be 29 in this example
    }
}

Person person = new Person("David", 29);
于 2009-02-17T22:05:57.567 に答える
0

まあ、他の人が言ったように、パラメーターなしのコンストラクターが最初に実行されたので、あなたの困惑です。

ただし、Age 変数の自動プロパティではなくフィールドを設定した場合は、お尋ねする必要がありますか?

public class Person
{
    private int _age;

    public int Age
    {
        get { return _age; }
        set { _age = value; }
    }
 }

それで十分な場合、または本当に使用する必要がある場合は、_age代わりに使用できます。xx

public class Person
{
    private int _age;
    private int x;

    public int Age
    {
        get { return _age; }
        set 
        { 
            _age = value;
            x = _age;
        }
    }
 }

どちらかがより適切です。

于 2009-02-17T22:39:25.570 に答える