4

重複の可能性:
C# のプロパティと変数の違いは何ですか

私は数週間前に C# を使い始めましたが、これは私を悩ませてきたものです。C# では、これらのいわゆる「魔法の」ゲッターとセッター (「シンタクティカル シュガー」とも呼ばれます) を使用できます。だから、私はこのようなことができます:

public int myInt { get; set; }

しかし、カプセル化の観点からは、これは無意味です。1 つは、データ メンバーがpublicであり、ドット演算子を使用して取得/設定できることです。ただし、これを行うと:

private int myInt { get; set; }

のように、まったくアクセスできませんmyInt is inaccessible due to protection level。これは実際に何をしているのですか?これはデータのカプセル化を実現する簡単な方法だと思っていたので、これを行う必要はありません。

private int myInt;
public void setMyInt(int i) { myInt = i; }
public int getMyInt() { return myInt; }

しかし、そうではありません。私が知る限り、これらの変数を公開しているだけです。私は多分私は何かのようなことができるだろうと思った

public int myInt { get; }

したがって、クライアントはgetそれを行うことができますが、そうではありませsetんが、パブリック アクセスは引き続き許可されます。それで、何が得られますか?

編集 特定のことをしようとしているわけではありません。これが実際にどのように機能するかを理解したいだけです。明確にするために:

変数を作成してpublicも、特にドット演算子でアクセスできる場合、カプセル化は達成されません。変数の getter と setterprivateを作成すると、変数を変更できますが、それが実際にどのように行われるかをより詳細に制御できます。

4

5 に答える 5

7

その目的は、将来の変更を通じてカプセル化を維持することです。

最初に自動ゲッターとセッターを使用してクラスを作成する場合:

public int Count { get; set; }

次に、次のように変更すると、まったく同じ外部インターフェイスが維持されます

public int Count {
    get { /* very complicated logic */ }
    set { /* even more complicated logic */ }
}

自動のものは、最初は単純なプロパティを支援するためのものです。

于 2012-07-25T14:36:36.880 に答える
6

あなたは書き込もうとしています

public int MyInt { get; private set; }

編集:自動実装されたプロパティのポイントは、追加のカプセル化を提供することではなく、フィールドを回避することです。
パブリックフィールド()を使用してクラスを作成し、publit int MyInt;誰かがそのフィールドを使用した場合、後でプロパティに変更することはできません。そうしないと、それを使用するコンパイル済みアセンブリが破損します。

自動プロパティを使用すると、フィールドと同じ単純さと簡潔さが得られますが、後で何も壊すことなく、本格的なプロパティ(追加のロジックを含む)に置き換えることができます。

于 2012-07-25T14:34:18.900 に答える
6

この「魔法の」ゲッターとセッターを呼び出すと、実際にはJavaの場合と同じようにメソッドが作成されます。そのため、カプセル化isは、IMOの見た目をすっきりさせてそれを維持しました。

プロパティ自体は、public int Property {get;set;}たとえば宣言されていても、実際にはバッキングフィールドとagetterおよびsetterメソッドを持っています。

この不自然な例を参照してください。

class A
{
   public int ID {get;set;}
}

今、あなたが次のようなことをするとき:

A a = new A();
a.ID=5;

生成されるILコードは次のようになります。

A.get_ID:    //getter method
IL_0000:  ldarg.0     
IL_0001:  ldfld       UserQuery+A.<ID>k__BackingField 
IL_0006:  ret         

A.set_ID:   //setter method
IL_0000:  ldarg.0     
IL_0001:  ldarg.1     
IL_0002:  stfld       UserQuery+A.<ID>k__BackingField
IL_0007:  ret         

そうです、やっていa.ID=5ます; メンバー変数に直接アクセスしているように見えますが、実際にはメソッドを呼び出しています。この場合、set_IDメソッド。

于 2012-07-25T14:35:33.650 に答える
0

公開しているだけです。プライベートセットを指定する場合は、次のようにすることができます。

   int myInt { get; private set; }
于 2012-07-25T14:35:05.230 に答える
0

これを行うことができます。これは非常に便利です。

public int myInt { get; プライベートセット; }

于 2012-07-25T14:35:48.970 に答える