web-dev-qa-db-ja.com

アクセサの取得と設定の仕組み

C#およびVB.NETでgetおよびsetアクセサーを実装する標準的な方法は、パブリックプロパティを使用して、対応するプライベート変数の値を設定および取得することです。これは変数の異なるインスタンスの影響がないと言ってもいいですか?つまり、オブジェクトの異なるインスタンス化がある場合、それらのインスタンスとそのプロパティは完全に独立しています。だから私は、プライベート変数の設定はgetおよびsetパターンを実装するための単なる構造であるという理解は正しいと思いますか?これについて100%確信はありませんでした。

4
Chris Halcrow

あなたはこの質問まで正しいです:

だから私は、プライベート変数の設定はgetおよびsetパターンを実装するための単なる構造であるという理解は正しいと思いますか?

全く逆のことが言えます。理想的には、カプセル化するオブジェクトのみが、カプセル化するオブジェクトに直接アクセスできる必要があります。これは デメテルの法則 として知られています。

実際には、この「法則」(ほとんどのプログラミング法と同様)を忠実に実行すると、過剰なエンジニアリングにつながる可能性がありますが、覚えておくのは非常に良い原則です。

すべてのプライベートフィールドに盲目的に実装する前に、ゲッターとセッターの存在を正当化する必要があるように、メンタルシフトを行います。

7
pdr

オブジェクトの異なるインスタンス化がある場合、それらのインスタンスとそのプロパティは完全に独立しています

はい、そうです。

だから私は、プライベート変数の設定はgetおよびsetパターンを実装できる単なる構造であるという理解は正しいと思いますか?

その意味がわからない。

4
Oded

だから私は、プライベート変数の設定はgetおよびsetパターンを実装するための単なる構造であるという理解は正しいと思いますか?

それは真ではありません。プライベートセッターは値をカプセル化しており、クラスのプロパティへの直接アクセスを許可しません。 ドメイン駆動開発 で広く使用されているプログラミング原則の1つです。

0
Yusubov

OK申し訳ありません-私の質問をもう一度読んで、100%明確ではなかったので、このパターンを使用する根拠を知りたい人を支援するためのget/setの使用に関する説明の組み合わせを次に示します(PDRに感謝-私はあなたの回答に賛成しましたこれは、この説明を作成するのに最も役立ちました):

  • オブジェクト指向プログラミング(.NETを含む)のget/setパターンは、次のようなパターンです(VB.Netの場合):

    Private _Organisation As String
    Public Property Organisation() As String
        Get
            Return _Organisation
        End Get
        Set(ByVal value As String)
            _Organisation = value
        End Set
    End Property
    
  • Get/setパターンは、インスタンス化されたクラスのプロパティインスタンスの設定または取得中にロジックを追加できる構造を提供するパターンとして使用されます。これは、さまざまなプログラミングシナリオで役立ちます。

  • このパターンが実装されているが、「get」または「set」メソッドで実際にロジックが実行されない場合、パターンは「オーバーエンジニアリング」を構成する可能性のある不要なコードを追加する可能性があります。すべてのプロパティが取得/設定パターンを使用する必要はありません
  • プロパティは 'get'アクセサーのみを持つことができます。これは、そのプロパティを読み取り専用にするために行われます
  • Get/setパターンを実装する場合、中間変数は、値を入れたり値を抽出したりするためのコンテナーとして使用されます。通常、中間変数の前にはアンダースコアが付けられます。
  • この中間変数は、get/set呼び出しを介してのみアクセスできるようにするためにプライベートにして、アプリケーションでより疎結合にする必要があります(詳細については、「pdr」からのこの質問への回答を参照してください)。
  • 中間変数は単に、get/setパターンを実装するときに使用する必要がある手法です。この中間変数を設定しても、オブジェクトのさまざまなインスタンスにわたって変数を「保護」することには影響がありません。オブジェクトのインスタンスとそのプロパティ値は完全に独立しています
0
Chris Halcrow

これについて:

だから私は、プライベート変数の設定はgetおよびsetパターンを実装するための単なる構造であるという理解は正しいと思いますか?

プロパティは、基礎となるフィールドを公開するだけでなく、もっと多くのことができるメソッドと考えることができます。プロパティは、複数のプライベートフィールドへのアクセスを提供することもできます。

たとえば、Invoiceプロパティを持つTotalPriceを作成できます。このプロパティは、すべてのItem(請求書の_List<Item>_プロパティ)の価格の合計などを返します。

このようにして、請求書の内部動作をカプセル化し、この単純なプロパティだけを公開します。プロパティのgetメソッドでは、価格を計算するために他のメソッドまたはプロパティをさまざまに呼び出すことができます。

Itemには、pricequantityのプライベートフィールドと、return (price * quantity)になるプロパティPriceを含めることができます。次に、discountをミックスに追加し、Priceを使用しているものからのItemへのアクセスは同じままです。

さらに、プロパティを読み取り専用(setメソッドなし)にすることもできます。この場合、アイテムの価格は変更できますが、合計は直接変更できません。これにより、データの整合性が保たれます。

プロパティをフィールドではなくメソッドと考える方が便利だと思います。プロパティを操作すると、そのプロパティへのすべての呼び出しを変更せずにデータが返される方法を変更できます(完全に返すのではなく、返す前にフィールドを処理できるため)クライアントへのフィールド)。

0
Ivan Pintar

以下のセッターの中間言語を見ると:

private string _bar;
private string Bar
{
    get
    {
        return this._bar;
    }
    set
    {
        this._bar = value;
    }
}

それからあなたは見るでしょう:

.method private hidebysig specialname instance string get_Bar() cil managed
{
    // Irrelevant to this question
}

中括弧内のすべてを無視すると、クラス内の通常のメソッドと同様に機能することがわかります。ゲッターとセッターは砂糖の構文と考えることができます。

メソッドの代わりにプロパティを使用する必要がある場合、およびそれらに必要なアクセス修飾子については、まったく別の議論がありますが、それはこの質問の範囲外です。

最後に、クラスは単なる青写真です。ブループリント(クラス)からオブジェクトをインスタンス化すると、そのロジックはカプセル化されるため、このオブジェクトのプロパティにアクセスしても、同じクラスからインスタンス化された他のオブジェクトには影響しません。

リファレンス: https://stackoverflow.com/questions/4184755/net-il-property-setter

0
CodeART