2013-06-02 12 views
5

とC#のプロパティ私のように定義されたプロパティを持っている...ハードコーディングされたゲッターとセッター

public List<Obj> Objs { get; set; } 

は、getメソッドにいくつかのロジックを置くことですので、それはなります何かのように...

public List<Obj> Objs 
{ 
    get 
    { 
     if (Objs == null) 
     { 
      Objs = new List<Obj>(); 
     } 
     if (Objs.Count < 1) 
     { 
      Objs.Add(new Obj()); 
     } 
     return Objs; 
    } 
    set { Objs = value; } 
} 

これを行うと、関数がすべてのパスで再帰的であることがわかります。

プライベートバッキングフィールドを作成せずにこれを行う方法はありますか?

+1

しないでください。http://msdn.microsoft.com/en-us/library/ms182327.aspx – SLaks

+1

なぜバッキングフィールドではできませんか? – Default

+0

彼らが働いているシステムを悪用することは、創造的な人々がどのようにしているか信じられないほどです。そして、幸運はあなたのために、コンパイラはそれ以外の質問はあなたがバッキングフィールドを使用してこの問題を解決しても、あなたがそれを行うべきではありません –

答えて

12

private List<Obj> _objs; 
    public List<Obj> Objs 
    { 
     get 
     { 
      if (_objs== null) 
      { 
       _objs= new List<Obj>(); 
      } 
      if (_objs.Count < 1) 
      { 
       _objs.Add(new Obj()); 
      } 
      return _objs; 
     } 
     set { _objs= value; } 
    } 

なぜそれは不可能でしょうか?

private List<Obj> objs; 
    public List<Obj> getListObjs() 
    { 
     ... 
     // Recursion 
     return getListObjs(); 
    } 
+0

これを行う方法はありません。 –

+0

なぜJavaで例を作成する(ちなみに、私には有効なC#コードのように見える)?同じロジックをC#に適用できないでしょうか? – Default

+0

C#のgetter/setterの略語は、多くの言語で見られるものではないため、初心者によっては再帰がなぜ発生しないのか理解できない場合があります。したがって、実際にゲッターを書くためにもっと標準的な方法で何をするかを示すことは面白いと感じました。 –

3

いいえバッキングフィールドなしで行う方法はありません。質問とは関係なく、状況に関連しています。一般的に、コレクションのセッターは公開せず、ゲッターだけを公開するべきです。あなたが非常に頻繁にオブジェクトの内部状態を公開しているセッターを持っている場合、それは隠されている必要があります。あなたは、プライベートフィールドを作るためにを持っている

0

Objのリストを格納するためにプライベートフィールドを使用する必要があります。 getメソッドのgetメソッドからデータを取得できません。:)は再帰です。

private List<Obj> _objs; 
public List<Obj> Objs 
{ 
    get { 
    if (_objs== null) 
    { 
     _objs = new List<Obj>(); 
    } 
    if (_objs.Count < 1) 
    { 
     _objs.Add(new Obj()); 
    } 
    return _objs; 
} 
    set { _objs= value; } 
} 
1

あなたのプロパティは、プロパティのgetの定義でそれ自身を参照します。ゲッターが無限ループに陥るので、これは違法です。自動実装されたプロパティ(最初の例)、またはバッキングフィールドを持つプロパティ(自動実装されたプロパティの場合はコンパイラによって自動的に生成されます)のいずれかです。プロパティのバッキングストアとして(好ましくはプライベート)フィールドを追加する必要があります。

private List<Obj> objs; 

public List<Obj> Objs 
{ 
    get 
    { 
     if (objs == null) 
     { 
      objs = new List<Obj>(); 
     } 
     if (objs.Count < 1) 
     { 
      objs.Add(new Obj()); 
     } 
     return objs; 
    } 
    set { objs = value; } 
} 
0

いいえ、実際はありません。

if (Objs == null)をチェックすると、実際に現在のgetメソッドが使用されているので、Objs { get; }はそれ自身を呼び出すため、常に再帰的です。

自動プロパティ(get; set;)は、バッキングフィールドと別のgetおよびsetメソッドを持つための略語です。 )(どのようGetObjsに気づく複数回自体を呼び出している -

private List<Obj> _objs; 
public List<Obj> GetObjs() { return _objs; } 
public void SetObjs(List<Objs> objs) { _objs = objs; } 

は、あなたが本当にあなたの記事で実装していることはこれです:その魔法がなければ、あなたのコードは次のようになります。だから、それが自分自身を呼び出すたびに、それは最終的にそれ自身を再び呼び出すことにつながるでしょう。そして再び、そして再び:

public List<Obj> GetObjs() { 
    if (GetObjs() == null) 
    { 
     SetObjs(new List<Obj>()); 
    } 
    if (GetObjs().Count < 1) 
    { 
     GetObjs().Add(new Obj()); 
    } 
    return GetObjs(); 
} 
0
private List<Obj> objs = new List<Obj>() { new Obj() }; 
public List<Obj> Objs { get { return objs; } } 

またはあなたが最後のObj

private List<Obj> objs = new List<Obj>(); 
public List<Obj> Objs 
{ 
    get 
    { 
     if (objs.Count == 0) objs.Add(new Obj()); 
     return objs; 
    } 
} 

を取り除く誰かから保護したい場合は、公開セットの目的は何でしょうか?

関連する問題