2017-02-17 5 views
0

私はC#を初めてお使いになり、C#の基本的な内容を調べています。セットというプロパティがあります。私が見つけたのは、setのアクセサまたは修飾子を取得することは、主にプライベートフィールドからの値の格納と取得に使用されます。C#でsetプロパティがどのように機能するのですか?

この場合、パブリックフィールドの使用にはどのような問題がありますか?

もう一つは、と設定してを書きました。コードは

public int Number 
    { 
     get 
     { 
      if(Number>10)return 10; 
      else 
      { 
       return Number; 
      } 
     } 
     set 
     { 
      if (value > 10) 
      { 
       Number = 10; 
      } 
      else 
      { 
       Number = value; 
      }     
     } 
    } 

ここで問題は何ですか?

もう1つの興味深いのは、VSで条件を確認するところに再帰的な記号が表示されます。誰かが説明できるのでしょうか?

enter image description here

私はC#に新しいですし、基本から学びたいです。 ありがとうございます。

+0

https://www.google.fr/?gws_rd=ssl#q=What+is+the+problem+with+using+public+fields – Joe

+1

ここで問題は何ですか?何も表示されません、例外がスローされるか、期待どおりに機能しません。 – Gusman

+1

[documentation](https://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx)と[チュートリアル](https://msdn.microsoft.com/en-us/library)を見てきましたか。 /aa288470(v=vs.71).aspx)? – clcto

答えて

5

最初の問題 - StackOverflowの

問題がNumberプロパティのためのあなたのgetterとsetterがNumberプロパティを取得および設定されているので、あなたが誤って、スタックオーバーフローにつながるしようとしている、再帰を使用していることです、バッキングフィールドではなく、

それは非常に少なくとも、このように変更する必要があります

private int number; 

public int Number 
{ 
    get 
    { 
     if(this.number>10)return 10; 
     else 
     { 
      return this.number; 
     } 
    } 
    set 
    { 
     if (value > 10) 
     { 
      this.number = 10; 
     } 
     else 
     { 
      this.number = value; 
     }     
    } 
} 
+0

「this」ということに注意してください。ここでは必要ありません。たとえば、「返品番号」が好きです。 – Polyfun

+0

私は知っているが、私は 'this'を好む。 StyleCopはそれを必要としました(少なくともしばらく前)。メソッド/プロパティなどのスコープではなく、クラスにスコープが設定されていることが明らかになります。 –

+0

@sethflowersクラスフィールドには、アンダースコア( '_number')を接頭辞として付けるなど、特定の命名規則を採用するか、私の会社のケースでは、小文字のm( 'mNumber')です。 – Kyle

2

あなたはプライベートバッキングフィールドが欠落しています。あなたのプロパティは自己参照型です(したがって再帰シンボル)。

代わりにこれを試してみてください:

private int _number; 

public int Number 
{ 
    get 
    { 
     if(_number > 10) 
     { 
      return 10; 
     } 
     else 
     { 
      return _number; 
     } 
    } 
    set 
    { 
     if (value > 10) 
     { 
      _number = 10; 
     } 
     else 
     { 
      _number = value; 
     }     
    } 
} 
1

を限り、私はあなたのコード内の番号を複数回呼び出している言うことができるように。 そして、それは私があなたのコードを実行したのStackOverflow :)

に実行されるまで再帰ループは永久に実行されます:

this.Number = 100; 
int num = this.Number; 

は基本的に、これはセッターとゲッターをトリガする必要があります。 if節が数値を10に設定しているときは、再度数値を設定しているので、最初の再帰が入力されます。

private int number; // Backing field 
public int Number 
{ 
    get { return number; } // Getter 
    set { number = value; } // Setter 
} 
1

公共の読み取り/書き込みアクセスを持つプロパティの主なアイデアは単純になることです。それはこのように、数の上にバッキングフィールドを追加しますNumber=10

によって再帰的に10に番号を設定しようとしますミューテータとアクセッサを含んでいます。

これらのget/setメソッドの内部に条件付きロジックがあると、クラスのコンシューマとの「契約」が壊れています....私は

var number = anInstance.Number; 

アクセサ/ゲッターを呼び出すとき...私はanInstanceオブジェクトの数ではなく、それのいくつかのロジック駆動型誘導体の現在の状態を受け取ることを期待しています。同様にミューテーター/セッター

anInstance.Number = 123; 

のための...私はそれが自動的にanInstanceオブジェクトの数の内部状態を設定することを期待します。

私は1つのステートメントでNumberを設定した場合...

anInstance.Number = 123; // I expect anInstance to have an internal state of 123 for it's Number 
var x = anInstance.Number; // I expect 123 back, not 10 

...私はその次の行にその値を取得する場合、私は戻って同じ値を期待していますが、あなたの現在の実装と(もしそれも再帰的ではありませんでした)、Numberを123に設定すると、これは無視され、10の値は新しい内部状態として保存され、その後Numberを取得すると10の値が返されます。

Numberプロパティは、呼び出し元が要求したものを変更することが重要ではありません。 sの値。 Numberプロパティの起動者は、その指示に従う必要があり、起動者は機能するためには、奇妙な内部ゲッター設定ロジックについて知っている必要はありません。

実際に条件付きで物事を取得/設定する必要がある場合、条件付きロジックの場所はNumberプロパティを含むクラスの外にあります。つまり、Numberプロパティを単純な自動実装ゲッターセッターで置き換え、次のようにします。

int x = anInstance.Number > 10 ? 10 : anInstance.Number; // replaced getter logic outside the class containing the `Number` property 
anInstance.Number = x > 10 ? 10 : x; // replaced setter logic 

再帰シンボルが表示される理由は、コードが再帰的に自身を呼び出すためです。 Numberプロパティは、いくつかのバッキングフィールドではなく、それ自身を呼び出しています。あなたはこの単純な方法であなたの財産を使用するときにプライベートバッキングフィールドを持つ必要がないこと、しかし、...プロパティはようになり

private int number; 
public int Number 
{ 
    get 
    { 
     return number; // note the lower-case 'n' refers to the private field instead of the property 
    } 
    set 
    { 
     number = value; 
    } 
} 

注意を変更します。完全な読み書きアクセスを行うことを意図している場合は、単純にパブリックフィールドを使用できます。

public int Number; 

ただし、プロパティを使用すると、フィールドへのアクセスを制御できます。

public int Number { get; private set; } 

単純なパブリックプロパティでは許可されていませんが、readonly修飾子を使用してこの動作を行うことはできます。

public readonly int Number; 

しかし、フィールドを使用して、上のプロパティを使用することの別の利点は、例がでMSDN

class TimePeriod 
{ 
    private double seconds; 

    public double Hours 
    { 
     get { return seconds/3600; } 
     set { seconds = value * 3600; } 
    } 
} 

から取得され、それが格納されている/使用方法の内部状態をより詳細に制御を提供できることegthisありますこの例では、このクラスのHoursプロパティの呼び出し元が時間の値を取得して設定していますが、フードの下では、クラスの内部状態は秒を使用して格納/取得しています。これは公共の場では不可能です。

+0

次に、私は公共の変数を使用する場合、問題は何ですか?パブリックフィールドの使用とプライベート変数のget setプロパティの使用の違いは何ですか? –

関連する問題