2016-03-29 10 views
1

私はプログラミング、特にオブジェクト指向プログラミングについて学びたいと思っています。クラスプロパティの実装スタイル

プロパティを作成する方法について説明した本がありますが、プライベート変数と組み合わせることもできます。私はなぜ彼らがこれを行うのか、これを行うことの利点は何であるか理解できません。

ここにサンプルコードを示します。

私は別の例として、このように書いています。

Class Person 
    Public Property Name() As String 
End Class 
+1

私が理解する限り、最後の例は自動実装されたプロパティです。彼らはそれほど遠くない(おそらく5年前に)導入されました。それ以前に本が出版されたのかもしれませんか?後の章では、著者は自動実装のプロパティを導入し、この本の以前の例と比較してより良い構文を表示します。 – Disappointed

+0

最後の例は、コンパイラがあなたのためにプライベート変数を生成するようにします。プライベート変数を使用する理由は、取得/設定時に計算/アクションを実行する場合や、 'ReadOnly'プロパティがある場合です。 –

答えて

1
  1. 最初に述べたアプローチは、.NET 3.5までプロパティを書き込むことができる唯一の方法でした。

  2. 第2のものはAuto-Implemented Propertyと呼ばれ、C#3.0/.NET 3.5で導入されました。

内部的には、自動実装されたプロパティも内部変数を使用してデータを格納します。コンパイラによって追加された唯一の構文的な砂糖は、開発者に少し時間をかけずにコードを読みやすくします。

なぜ自動的に実装されたプロパティを使用するのではなく、可視の宣言された変数を使用するのですか?

これは、プログラムのコンテキストによって異なります。名前変数のパブリックマッパーを1:1にしたい場合は、自動実装を行うことができます。

しかし、変数の値を設定/取得するときに、がある場合は、余分な変数のアプローチを使用するのに、が必要です。

アプリ内の名前が50文字を超えないようにする必要があるとします。

Set(ByVal value As String) 
     If value.Length <= 50      
      _Name = value 
     Else 
      'Throw some validation error 
     End if 
    End Set 

これは、変数(ここで_Name)を定義した場合にのみ行うことができます。自動実装されたプロパティではこれを行うことはできません。

あなたが詳細に興味がある場合:あなたが見ることができるように

Person.get_Name: 
IL_0000: nop   
IL_0001: ldarg.0  
IL_0002: ldfld  UserQuery+Person._Name 
IL_0007: stloc.0  // Name 
IL_0008: br.s  IL_000A 
IL_000A: ldloc.0  // Name 
IL_000B: ret   

Person.set_Name: 
IL_0000: nop   
IL_0001: ldarg.0  
IL_0002: ldarg.1  
IL_0003: stfld  UserQuery+Person._Name 
IL_0008: nop   
IL_0009: ret  

Person.get_Name: 
IL_0000: ldarg.0  
IL_0001: ldfld  UserQuery+Person._Name 
IL_0006: stloc.0  
IL_0007: br.s  IL_0009 
IL_0009: ldloc.0  
IL_000A: ret   

Person.set_Name: 
IL_0000: ldarg.0  
IL_0001: ldarg.1  
IL_0002: stfld  UserQuery+Person._Name 
IL_0007: nop   
IL_0008: ret 

は、あなたのコードスニペットの両方が(ほぼ)同じMSILを生成両方のスニペットは、文字列値をvaribale _Name(stfld)に読み書きします。 (唯一の差分は、デバッグ中に使用されるnopコマンドですが、ここで無視することができます)

+0

Re:VBで有効な構文である 'Get'構文についてのあなたの質問 - プロシージャ名" variable "の値を値に設定し、関数が終了すると返されます。 –

+0

あなたは絶対に正しいです。私はちょうど昨年のVBで働いていないとその "機能"を忘れてしまった。私は答えからその部分を削除しました。 –

1

which is alot cleaner is my opinion

後者は、自動実装プロパティと呼ばれます。コンパイラは、ボイラープレートコードを削減できるバッキングフィールドを提供します。あなたのコードで_Nameプライベートメンバーを参照することはできます。

より良い/クリーナーによって異なります。同様の例は、コレクションクラスの読み取り専用Count財産になり

Public ReadOnly Property Age As Integer 
    Get 
     If DateOfBirth <> DateTime.MinValue Then 
      Return (DateTime.Now.Year - DateOfBirth.Year) 
     Else 
      Return 0 
     End If 
    End Get 
End Property 

:あなたはこのような状況のためのフルバージョンが必要です。または:

Private _name As String = "" 
Public Property Name As String 
    Get 
     Return _name 
    End Get 
    Set(value As String) 
     If _name.ToLowerInvariant <> value.ToLowerInvariant Then 
      _name = value 
      NotifyPropertyChanged() 
     End If 
    End Set 
End Property 

自動実装バージョンが使用できないことがあります。本として、私はVSの古いバージョンを持っている人のために少なくとも両方の方法をカバー/表示することを期待しています。

自動実装されたプロパティはVS 2010で利用可能になりました。 NET Frameworkのバージョンはコンパイラ機能であるため問題ありません。

1

private variableの理由は、このclass内でのみアクセスする必要があります。 よく見ると、Namevariableという_Nameと呼ばれるpropertyが表示されます。それはnaming conventionであり、それを使用する必要があります。そのvariableは、同じクラスからでも、property以外のものにアクセスすべきではありません。

これは、別のclassesおよびprojectsからアクセスされると言われているpropertypublicです。

あなたは、プロパティの共通のルックを発表:

Private _Name As String 
Public Property Name() As String 
    Get               ' (1) 
     Name = _Name 
    End Get 
    Set(ByVal value As String)          ' (2) 
     _Name = value 
    End Set 
End Property 

は他には書き込み専用、読み取り専用inlude:

Private _Name As String 
Public ReadOnly Property Name() As String 
    Get               ' (1) 
     Name = _Name 
    End Get 
End Property 

もう一つの良い例は次のようになります。

Private _Name As String 
    Public ReadOnly Property Name() As String 
    Get               ' (1) 
     If Strinf.IsnullOrEmpty(_Name) 
      _Name = Somemethod() 
     End if 
     Return _Name 
    End Get 
End Property 

このプロパティは時に初期化されます最初に使用されます。

関連する問題