2013-06-02 12 views
5

Mam właściwość określona jako ...C# obiektu z zakodowanego getter i setter

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

Co chciałbym być w stanie zrobić, to włożyć trochę logiki do metody GET, tak to będzie wyglądać coś jak ...

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

teraz gdy to zrobić pojawia się błąd informujący mnie, że funkcja jest rekurencyjna na wszystkich ścieżkach.

Czy można to zrobić bez tworzenia prywatnego pola wsparcia?

+1

Nie rób tego.http://msdn.microsoft.com/en-us/library/ms182327.aspx – SLaks

+1

Dlaczego nie możesz tego zrobić z polem pomocniczym? – Default

+0

To niesamowite, jak kreatywni są ludzie, jeśli chodzi o nadużycie systemu, z którym pracują. I na szczęście kompilator był na tyle sprytny, by wiedzieć, że próbujesz nadużywać systemu, w przeciwnym razie pytanie brzmiałoby: "Dlaczego moja aplikacja się zawiesza". –

Odpowiedz

12

Masz aby prywatną murawę:

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

Dlaczego jest to niemożliwe? Zróbmy to samo w Javie:

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

Nie można tego zrobić. –

+0

dlaczego utworzyć przykład w java (przy okazji, wygląda mi to na prawidłowy kod C# do mnie)? Czy ta sama logika nie miałaby zastosowania w języku C#? – Default

+0

Zbiór skrótów w języku C# nie jest czymś, co można zobaczyć w wielu językach, więc niektórzy początkujący mogą nie rozumieć, dlaczego występuje rekursja. Dlatego czułem, że byłoby ciekawie pokazać to, co on faktycznie robi w bardziej standardowy sposób, aby napisać gettera. –

3

Nie można tego zrobić bez pola zaplecza. Niezwiązane z pytaniem, ale związane z sytuacją. Powinieneś na ogół nie wystawiać setera do kolekcji, ale tylko gettera. Jeśli masz setera, bardzo często wystawiasz wewnętrzny stan obiektu, który powinien być ukryty.

0

powinieneś używać prywatnego pola do przechowywania listy Objs. Nie można uzyskać danych z metody get get ... :) jest rekursją.

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

Twoja własność odnosi się do siebie w definicji części nieruchomości z numerem get. Jest to nielegalne, ponieważ mogłoby spowodować, że getter zakończy się niekończącą się pętlą. Masz albo właściwość zaimplementowaną automatycznie (twój pierwszy przykład), albo właściwość z polem pomocniczym (która jest automatycznie generowana przez kompilator dla właściwości z automatycznym wdrożeniem). Musisz dodać (preferowane prywatne) pole jako zaplecze do swojej nieruchomości:

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

Nie, niezupełnie.

W kodzie sprawdzając, czy jest if (Objs == null) - skutecznie używasz metody get, w której aktualnie się znajdujesz. Tak więc Objs { get; } wywołuje samą siebie, dlatego zawsze jest rekursywna.

Należy pamiętać, że właściwości automatyczne (get; set;) są w istocie skrótem dla pola zaplecza i oddzielnych metod pobierania i ustawiania. Bez tej magii, Twój kod będzie wyglądać następująco:

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

Jaki jesteś naprawdę wdrożenia w swoim poście jest - Zauważ, jak GetObjs() powołuje się wielokrotnie. Tak więc za każdym razem, gdy się nazywa, w końcu doprowadzi do tego, że znowu się odezwie. I znowu, i znowu .:

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

lub jeśli chcesz chronić od kogoś Usunięcie ostatniego OBJ

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

Jaki byłby cel zestawu publicznej?

Powiązane problemy