102

私は現在 C# のクラスを受講しており、最善の方法を見つけようとしています。私は Java のバックグラウンドを持っているので、Java のベスト プラクティスしか知りません。私はC#初心者です!

Java では、プライベート プロパティがある場合、これを行います。

private String name;

public void setName(String name) {
   this.name = name;
}

public String getName() {
   return this.name;
}

C# では、これを行う方法がたくさんあることがわかります。

私はJavaのようにそれを行うことができます:

private string name;

public void setName(string name) {
   this.name = name;
}

public string getName() {
   return this.name;
}

または、次のようにすることもできます。

private string name;

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

または:

public string Name { get; set; }

どちらを使用する必要があり、各アプローチに関連する注意事項や微妙な点は何ですか? クラスを作成するときは、Java から知っている一般的なベスト プラクティスに従っています (特に、Effective Java を読んでいます)。たとえば、私は不変性を支持しています (必要な場合にのみセッターを提供します)。これらのプラクティスが、C# でセッターとゲッターを提供するさまざまな方法にどのように適合するかを知りたいだけです。基本的に、Java の世界のベスト プラクティスを C# に変換するにはどうすればよいでしょうか?

編集

これをJon Skeetの回答へのコメントとして投稿していましたが、長くなりました:

自明ではないプロパティ (つまり、重要な処理と検証を伴うもの) はどうですか? パブリック プロパティを介して公開できますが、ロジックはgetandにカプセル化されていsetますか? 専用のセッターとゲッターメソッド(関連する処理と検証ロジックを使用)を使用して、これを行う必要があるのはなぜですか。

4

12 に答える 12

96

C# 6 より前

些細なプロパティのために、これらの最後のものを使用します。ゲッターとセッターの両方がパブリックであるため、これをパブリックプロパティと呼ぶことに注意してください。

不変性は、自動的に実装されたプロパティでは少し面倒です。ゲッターしか持たない自動プロパティを書くことはできません。あなたが来ることができる最も近いです:

public string Foo { get; private set; }

これは実際には不変ではありませ...クラス外では不変です。したがって、代わりに実際の読み取り専用プロパティを使用したい場合があります。

private readonly string foo;
public string Foo { get { return foo; } }

あなたは絶対に書きたくないgetName()and setName(). 場合によっては、プロパティを使用するのではなく、Get/Set メソッドを記述する方が理にかなっている場合があります。特に、プロパティが高価になる可能性があり、それを強調したい場合です。ただし、メソッドについては PascalCase の .NET 命名規則に従う必要があり、とにかく、このような単純なプロパティを通常のメソッドで実装することは望ましくありません。ここでは、プロパティははるかに慣用的です。

C# 6

やっと、適切な読み取り専用の自動的に実装されたプロパティができました。

// This can only be assigned to within the constructor
public string Foo { get; }

同様に、何らかの作業を行う必要がある読み取り専用プロパティの場合、メンバー本体のプロパティを使用できます。

public double Area => height * width;
于 2011-02-09T18:21:01.007 に答える
17

必要なのがデータを格納する変数だけの場合:

public string Name { get; set; }

読み取り専用に表示させたいですか?

public string Name { get; private set; }

またはさらに良い...

private readonly string _name;

...

public string Name { get { return _name; } }

プロパティを割り当てる前に値のチェックを行いたいですか?

public string Name 
{
   get { return m_name; }
   set
   {
      if (value == null)
         throw new ArgumentNullException("value");

      m_name = value;
   }
}

一般に、GetXyz()とSetXyz()は特定の場合にのみ使用され、適切と思われるときに腸を使用する必要があります。一般に、ほとんどのget / setプロパティには多くのロジックが含まれておらず、予期しない副作用があったとしてもごくわずかであると思います。プロパティ値を読み取るために、要求しているオブジェクトを構築するためにサービスを呼び出すか、ユーザーから入力を取得する必要がある場合は、それをメソッドにラップしBuildXyz()、ではなく、のように呼び出しますGetXyz()

于 2011-02-09T18:34:21.377 に答える
13

get/set メソッドではなく、C# のプロパティを使用します。それらはあなたの便宜のためにそこにあり、それは慣用的です.

2 つの C# の例については、1 つは単純にもう 1 つのシンタックス シュガーです。インスタンス変数の単純なラッパーだけが必要な場合は auto プロパティを使用し、getter や setter にロジックを追加する必要がある場合はフル バージョンを使用します。

于 2011-02-09T18:21:53.047 に答える
5

C# では、get および/または set のプライベート フィールドを公開するためのプロパティを優先します。あなたが言及したフォームは、get と set が非表示のピボット バッキング フィールドを自動的に生成する自動プロパティです。

可能であれば自動プロパティを好みますが、C# で set/get メソッドのペアを実行しないでください。

于 2011-02-09T18:22:38.703 に答える
5
public string Name { get; set; }

これは単に自動実装されたプロパティであり、技術的には通常のプロパティと同じです。コンパイル時にバッキング フィールドが作成されます。

すべてのプロパティは最終的に関数に変換されるため、最終的にコンパイルされた実際の実装は、Java で慣れているものと同じです。

バッキング フィールドで特定の操作を行う必要がない場合は、自動実装プロパティを使用します。それ以外の場合は、通常のプロパティを使用してください。操作に副作用がある場合や計算コストが高い場合は get 関数と set 関数を使用し、それ以外の場合はプロパティを使用します。

于 2011-02-09T18:22:50.887 に答える
4

まず、あなたが書いたものを説明しようと思います。

// private member -- not a property
private string name;

/// public method -- not a property
public void setName(string name) {
   this.name = name;
}

/// public method -- not a property
public string getName() {
   return this.name;
}

// yes it is property structure before .Net 3.0
private string name;
public string Name {
   get { return name; }
   set { name = value; }
}

この構造は現在も使用されていますが、追加の機能を実行する場合に最適です。たとえば、値が設定されている場合は、値を解析して大文字にし、内部使用を変更するためにプライベートメンバーに保存できます。

.netFramework3.0を使用

// this style is introduced, which is more common, and suppose to be best
public string Name { get; set; }

//You can more customize it
public string Name
{
    get;
    private set;    // means value could be set internally, and accessed through out
}

C#での幸運を祈ります

于 2011-02-09T18:31:12.690 に答える
4

C# でどの方法を選択しても、最終結果は同じです。個別のゲッター メソッドとセッター メソッドを使用してバッキング変数を取得します。プロパティを使用することで、ベスト プラクティスに従っていることになるため、どれだけ詳細にするかが問題になります。

個人的には、最後のバージョンである auto-properties を選択しますpublic string Name { get; set; }。これは、占有するスペースが最も少ないためです。また、検証などを追加する必要がある場合は、いつでもこれらを拡張できます。

于 2011-02-09T18:20:55.070 に答える
4

string Name { get; set; }簡潔で読みやすいので、可能な限り public を好みます。ただし、これが必要な場合もあります

private string name;

public string Name {
   get { return name; }
   set { name = value; }
}
于 2011-02-09T18:22:24.710 に答える
4

getX()C# では、メソッドではなくプロパティを使用する方法が推奨されsetX()ます。また、C# では、プロパティに get と set の両方が含まれている必要がないことに注意してください。get-only プロパティと set-only プロパティを使用できます。

public boolean MyProperty
{
    get { return something; }
}

public boolean MyProperty
{
    set { this.something = value; }
}
于 2011-02-09T18:23:29.340 に答える
3

前述のように、これらのアプローチはすべて同じ結果になります。最も重要なことは、慣習を選び、それを守ることです。私は最後の 2 つのプロパティの例を使用することを好みます。

于 2011-02-09T18:23:19.537 に答える
2

ここでのほとんどの回答と同様に、自動プロパティを使用してください。直感的で、コード行が少なく、よりクリーンです。クラスをシリアル化する必要がある場合は、クラス[Serializable]/ を[DataConract]属性でマークします。そして、あなたが使用している場合は[DataContract]、メンバーにマークを付けます

[DataMember(Name="aMoreFriendlyName")]
public string Name { get; set; }

プライベートまたはパブリック セッターは、好みによって異なります。

また、自動プロパティにはゲッターとセッター (パブリックまたはプライベート) の両方が必要であることに注意してください。

/*this is invalid*/
public string Name 
{ 
    get; 
   /* setter omitted to prove the point*/
}

または、get/set のみが必要な場合は、自分でバッキング フィールドを作成します。

于 2011-02-09T18:39:06.147 に答える