2010-11-30 5 views
6

C#では、プライベート変数を宣言する必要なくプロパティを持つことができます。 このget;セット; C#の構文

'local variable(s) to hold property value(s) 
Private mvarPhoneNumber As String 'local copy 
Public Property Let PhoneNumber(ByVal vData As String) 
'used when assigning a value to the property, on the left side of an assignment. 
'Syntax: X.PhoneNumber = 5 
    mvarPhoneNumber = vData 
End Property 


Public Property Get PhoneNumber() As String 
'used when retrieving value of a property, on the right side of an assignment. 
'Syntax: Debug.Print X.PhoneNumber 
    PhoneNumber = mvarPhoneNumber 
End Property 

のように見えた私のVB6のコードは次のように見ることができます。

public string PhoneNumber{get;set;} 

C#のゲッターとセッターメソッドで検証を行うにはどうすればよいですか? このような検証を追加しようとしました。

public string PhoneNumber 
     { 
      get 
      { 
       return PhoneNumber; 
      } 
      set 
      { 
       if (value.Length <= 30) 
       { 
        PhoneNumber = value; 
       } 
       else 
       { 
        PhoneNumber = "EXCEEDS LENGTH"; 
       } 
      } 
     } 

このコードのget部分はコンパイルされません。 プライベート変数を使用する必要がありますか?

+0

Andrew氏によると、プロパティのプライベート変数を作成する必要があります。 C#の自動プロパティ機能は実際にあなたのために舞台裏でこれを行いますが、そのようにプライベート変数にアクセスすることはできません。それを使って何かをするように明示的に宣言しなければなりません(例えば、それを検証するなど) – Chris

+1

また、セッターでバッキングフィールドを設定するか、実行時にStackOverflowExceptionを実行します。 –

+0

例のために単純化しているのかどうかは分かりませんが、ArgumentExceptionを投げるのではなく、盲目的にプロパティを新しい値に設定するのはかなり難しいようです。 –

答えて

18

はい、あなたはバッキング・フィールドを作成する必要があります:

string _phoneNumber; 

public string PhoneNumber 
{ 
    get 
    { 
     return _phoneNumber; 
    } 
    set 
    { 
     if (value.Length <= 30) 
     { 
      _phoneNumber = value; 
     } 
     else 
     { 
      _phoneNumber = "EXCEEDS LENGTH"; 
     } 
    } 
} 

は、この実装は自動的に実装プロパティと変わらないことに注意してください。自動的に実装されるプロパティを使用する場合は、単にコンパイラにバッキングフィールドを作成させるだけです。 getまたはsetにカスタムロジックを追加する場合は、上記のようにフィールドを自分で作成する必要があります。

+0

ありがとうございます。私は必要があるかどうかわからなかった。 – abhi

1

はい、あります。ショートカットの "暗黙の"構文を使用すると、_phoneNumberというバッキングフィールドが作成されます。明示的にプロパティを定義するときは、独自のバッキングフィールドを作成する必要があります。右あなたの財産定義プット以上:

private string _phoneNumber; 

してから、プロパティのget使用中:いくつかの多くの選択肢のためにここに

get 
{ 
    return _phoneNumber; 
} 
+0

私はそれがそのように呼ばれているとは思わないが、長い醜い名前を持っています – CodesInChaos

2

必ずしもローカル変数が必要なわけではありません。理論的には、任意の機能をget/setプロパティ内に実装することができます。しかし、あなたの例では、あなたのget/setプロパティの再帰的なアクセスが実装されている方法では意味がありません。したがって、具体的には、ローカル変数が必要です。

2

NullReferenceExceptionを回避し、全体的なコードを短縮するために、私はこれを行うでしょう。

public string PhoneNumber 
{ 
    get { return _phoneNumber; } 
    set 
    { 
     var v = value ?? string.Empty; 
     _phoneNumber = v.Length <= 30 ? v : "EXCEEDS LENGTH"; 
    } 
} 
private string _phoneNumber; 
+0

おそらくあなたのセッターではなく、あなたのゲッターでnull値を処理する方が良いでしょう。プロパティが初期化される前にゲッターにアクセスするとどうなりますか?私はget {change _phoneNumber ?? string.Empty; }。また、指定された値が長すぎる場合は、任意の値で置き換えるのではなく、例外をスローする必要があります。 – Chris

+0

@Chris PhoneNumberをnullにすることはできません.CaaosPandionの答えは、以下のように仮定します。setterとコンストラクタで捕捉される必要があります(コンストラクタは決してオブジェクトを無効な状態にしてはいけません)。代わりに、nullになる可能性がある場合は、チェックなしでヌルを返すだけです(それを許可するようにチェックが変更されます)。 –

+0

@Chris - 個人的には、彼らが持っているバリデーションはかなり弱いと思いますが、それは一種の話題でした。解決するのが簡単なときに 'NullReferenceException'に脆弱なコードを立てることはできません。 @ジョンは彼の評価では絶対に正しいですが、私はおそらくそれをもう少し取って、不変のオブジェクトを使用します。 – ChaosPandion