2013-06-02 21 views
5

Ich habe eine Eigenschaft definiert als ...C# Immobilie mit hartcodiert Getter und Setter

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

Was würde ich zu tun, um der Lage sein mag, ist eine gewisse Logik in die get-Methode zu setzen, so dass es aussehen würde, so etwas wie ...

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; } 
} 

Nun, wenn ich dies tun, bekomme ich einen Fehler mir zu sagen, dass die Funktion auf allen Pfaden rekursiv ist.

Gibt es eine Möglichkeit, dies zu tun, ohne ein privates Backing-Feld zu erstellen?

+1

Tun Sie das nicht.http://msdn.microsoft.com/en-us/library/ms182327.aspx – SLaks

+1

Warum können Sie es nicht mit einem Backing-Feld tun? – Default

+0

Es ist unglaublich, wie kreativ Menschen sind, wenn es darum geht, ein System zu missbrauchen, mit dem sie arbeiten. Und zum Glück für Sie war der Compiler schlau genug zu wissen, dass Sie versuchen, das System zu missbrauchen, sonst wäre die Frage "Warum hängt meine App?" –

Antwort

12

Sie müssen ein privates Feld machen:

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; } 
    } 

Warum ist es unmöglich? Lets machen das gleiche in Java:

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

Keine Möglichkeit, dies zu tun. –

+0

Warum ein Beispiel in Java erstellen (übrigens sieht es für mich wie ein gültiger C# -Code aus)? Wäre nicht dieselbe Logik in C# anwendbar? – Default

+0

Die Getter/Setter-Kürzel in C# werden nicht in vielen Sprachen angezeigt, daher verstehen einige Anfänger möglicherweise nicht, warum Rekursion auftritt. Daher hatte ich das Gefühl, dass es interessant wäre, zu zeigen, was es eigentlich auf eine standardisierte Weise tut, um einen Getter zu schreiben. –

3

Nein, es gibt keine Möglichkeit, dies ohne ein Backing-Feld zu tun. Unabhängig von der Frage, aber bezogen auf die Situation. Sie sollten im Allgemeinen keinen Setter für eine Sammlung verfügbar machen, sondern nur einen Getter. Wenn Sie einen Setter haben, geben Sie sehr oft den internen Zustand des Objekts frei, das verborgen bleiben sollte.

0

sollten Sie private Feld verwenden, um Liste von Objs zu speichern. Sie können keine Daten von Get-Methode von Get-Methode abrufen ... :) ist Rekursion.

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

Ihre Eigenschaft bezieht sich auf die Definition des get Teil des Vermögens auf sich. Dies ist illegal, da der Getter in einer Endlosschleife enden würde. Sie haben entweder eine automatisch implementierte Eigenschaft (Ihr erstes Beispiel) oder eine Eigenschaft mit einem Hintergrundfeld (das vom Compiler automatisch für automatisch implementierte Eigenschaften generiert wird). Sie müssen ein (vorzugsweise privates) Feld als Backing-Store für Ihre Immobilie hinzufügen:

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

Nein, nicht wirklich.

In Ihrem Code, wenn Sie nach if (Objs == null) suchen - Sie verwenden effektiv die Get-Methode, in der Sie gerade sind. So ruft Objs { get; } sich selbst, und das ist, warum es immer rekursiv ist.

Denken Sie daran, dass Auto-Eigenschaften (get; set;) ist eigentlich nur eine Abkürzung für ein Backing-Feld und separate Get-und Set-Methoden. Ohne diese Magie, würde Ihr Code wie folgt aussehen:

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

Was sind Sie wirklich in Ihrem Beitrag Implementierung ist dies - feststellen, wie GetObjs() ruft sich mehrere Male. So wird es jedes Mal, wenn es sich selbst nennt, dazu führen, dass es sich selbst wieder anruft. Und wieder und wieder .:

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; } } 

oder wenn Sie von jemandem schützen wollen das letzte Obj Entfernen

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

Was ist der Zweck eines öffentlichen Satz wäre?