web-dev-qa-db-ja.com

プライベート変数のないC#カスタムgetter / setter

最近c#を学んだので、プロパティを書くことを学んだとき、次のようにそれをするように教えられました。

public string Name { get; set; }

自動プロパティは素晴らしいです!しかし、今はもう少し複雑なことをしようとしているので、カスタムアクセサーのペアを作成する必要があります。

private string _Name;
public string Name {
    get { return _Name; }
    set { _Name = value }
}

コンパイラーは、autosを使用するとプライベートインスタンス変数を暗くしますが、私は甘やかされており、そのプライベート変数が無意味に見えることを望んでいません。

プライベート変数なしでカスタムアクセサーを使用する方法はありますか?

51
Tin Can

プロパティには、バッキング変数(フィールド)はまったく必要ありません。これらは単純なフィールドをカプセル化するために使用できますが、他のデータにアクセスするためにも使用できます。

public Decimal GrandTotal { get { return FreightTotal + TaxTotal + LineTotal; } }

または

public string SomeStatus { get { return SomeMethodCall(); } }

目的が単にフィールドをプロパティでカプセル化することである場合、自動プロパティを使用していない場合、何らかのバッキングフィールドが必要になります。

38
jhappoldt

答えはいいえ、それはできません。再帰のためです。 (行番号9および7を参照):

Line 1  :   public string Name
Line 2  :   {
Line 3  :     get
Line 4  :     {
Line 5  :         return FirstName + " "  + LastName;
Line 6  :     }
Line 7  :     set
Line 8  :     {
Line 9  :         Name = value; // <-- Goes back to Line 7
Line 10 :     }
Line 11 :   }
11
tika

いいえ、私は恐れていません。コンパイラは、自動生成されたプロパティでこれを実現するのに十分スマートですが、標準のプロパティでは、そのようなものの背後にあるロジックが邪魔になり、善よりも害を及ぼすと思います。

たとえば、このようなプロパティを作成するとどうなりますか?.

public int SomeValue
{
  get
  {
    return 0;
  }
}

(探している機能を備えた)コンパイラは、バッキングプライベート変数を作成しますか?どうして?必要ありません。

さらに、コンパイル時までプライベート値が作成されない場合、コードで何を参照しますか:

public string Name {
  get { return _Name; }
  set { _Name = value }
}

_Nameとは何ですか? _Nameと呼ばれる別の値がある場合はどうなりますか?次に、コンパイラはこのプロパティのバッキング値を何と呼びますか? twoバッキング値が必要な場合はどうなりますか?コンパイラーはそのために十分賢いでしょうか?

public string Name
{
  get
  {
    return string.Format("{0} {1}", _FirstName, _LastName);
  }
  set
  {
    // some parsing magic
  }
}

以前に尋ねられましたが、近い将来、答えは「ノー」であり続けると思います。

自動プロパティは、単純な直接メンバーアクセスのための構文の省略形です。 (そして、その推進力の1つは、人々にpublic値の直接作成を停止させることだけであったと思います。)プロパティは、それをはるかに簡単に超えて複雑になる可能性があります。私が簡単にそれをするように言うことができることを理解してください。

10
David