2

次のことを守ってください...

//pattern 1
public class Cheesesteak
{
    public string bread {get; private set}
    public string cheese {get; private set}

    public Cheesesteak()
    {
        bread = "Amoroso"; 
        cheese = "Cheez Whiz";
    }
}

//pattern 2
public class Cheesesteak
{
    public string bread 
    {
        get {return bread;}
        set 
        {
            bread = "Amoroso";
        }
    }
    public string cheese 
    {
        get {return cheese;}
        set
        {
            cheese = "Cheez Whiz";
        }
    }
    public Cheesesteak() {}
}

これは好奇心の質問です。コンストラクターで変数を宣言するのではなく、「セット」の定義で変数を設定する利点や特定の理由はありますか? 私の最初の推測では、パターン 1 の方が短いですが、コンパイル中の効率は低くなります。

4

3 に答える 3

8

コンストラクターで変数を宣言するのではなく、「セット」の定義で変数を設定する利点や特定の理由はありますか?

いいえ、実際、これはおそらくあなたが望んでいるものではありません。これにより、"break" または "cheese" を設定できbread = "rye";なくなりStackOverflowExceptionます。StackOverflowExceptionまた、コードで値を取得しようとすると が発生し、プロパティ ゲッターはバッキング フィールドの値ではなくプロパティを返すことにも注意してください。

あなたはおそらくこれについて考えていました:

public class Cheesesteak
{
    private string bread = "Amoroso";
    public string Bread 
    {
        get {return bread;}
        set 
        {
            bread = value;
        }
    }

    // ...

ここでの唯一の利点は、フィールドが定義されている場所に「デフォルト」値を設定していることです。これにより、場合によっては保守性や読みやすさが向上し、定義されたコンストラクターが不要になる可能性さえあります。これにより、コード全体の長さが短縮される可能性があります。 .

私の最初の推測では、パターン 1 の方が短いですが、コンパイル中の効率は低くなります。

一般に、フィールドをインラインで設定するか、コンストラクターで設定するかによって、効率が低下することはありません。コンパイラは、型の実際のコンストラクターが最初にフィールドを設定してからコンストラクター コードを実行するようにするため、コンパイルされた IL に関しては両方のバージョンが (実用的な目的で) 同じになります。これは効率の問題ではなく、コードの読みやすさと保守性の問題です。

プロパティを常に定数にしたい (つまり、常に を返すBread必要がある) 場合は、プロパティにゲッターを持たせ、セッターを持たないようにすることができます。"Amoroso"

public string Bread { get { return "Amoroso"; } }

これは事実ではないと思いますが、あなたが意図したものである場合に備えて、オプションとして言及したいと思いました.

于 2013-01-09T21:30:05.693 に答える
1

2 番目のオプションではStackOverflowException、ユーザーがプロパティの割り当てまたはアクセスを試行するたびに結果が返されますが、最初のオプションではプロパティへのプライベート アクセスのみが許可されます。

あなたはおそらく次のようなことを意味していました:

private string bread = "Amaroso";
public string Bread
{
    get { return bread; }
    private set
    {
        bread = value;
    }
}

プロパティを「Amaroso」で初期化しますが、パブリックに設定することはできません。

于 2013-01-09T21:30:59.290 に答える
0

いいえ、それらは完全に異なります。getandブロックは、set実際には、プロパティの読み取りまたは書き込み時に実行されるメソッドです。どちら初期化とは関係ありません。

var x = thing.Property; // Property's "get" accessor method is executed
thing.Property = x; // Property's "set" accessor method is executed

2 番目の例では、両方のプロパティ アクセサーが自分自身を無限に再帰し、StackOverflowException を取得します。

于 2013-01-09T21:31:10.160 に答える