2011-07-28 9 views
5

Jestem nowy w składni C#. Pisałem następujące klasy (związanym kodzie dla masterpage mojej stronie internetowej):Pobierz i ustaw w C#

public partial class MasterPagePro : System.Web.UI.MasterPage 
{ 
    public String pageTitle 
    { 
     get 
     { 
      if (this.pageTitle == null) 
       return ""; 
      else 
       return " - " + this.pageTitle; 
     } 
    } 

} 

Jednak przy próbie dostępu PageTitle jak to w html:

<title>MySite<%=pageTitle%></title> 

pojawia się błąd stackoverflow. Patrząc na kod, jest całkiem jasne, że problem polega na tym, że metoda wywołuje się rekursywnie, ale nie wiem, co napisać, aby rozwiązać ten problem. Mógłbym zrobić coś w rodzaju:

public partial class MasterPagePro : System.Web.UI.MasterPage 
{ 
    private String _pageTitle 

    public String pageTitle 
    { 
     get 
     { 
      if (_pageTitle == null) 
       return ""; 
      else 
       return " - " + _pageTitle; 
     } 
     set { _pageTitle = value; } 
    } 
} 

Ale wydaje się, że w ogóle nie ma się mowy z syntaktycznym skrótem. Jaki jest właściwy sposób na zrobienie tego?

Odpowiedz

6

W pierwszym przykładzie spodziewasz się, że kompilator będzie wiedział, czy rzeczywiście chciałeś rekurencyjnie wywoływać tę samą właściwość. Ponieważ kompilator nie może poznać twoich intencji, utworzy kod tak, jak napisano, co, jak wskazałeś, prowadzi do stackoverflow.

Skrót syntaktyczny dotyczy sytuacji, gdy masz prostą właściwość z setera/programu pobierającego/powracającego. Kompilator tworzy dla ciebie element klasy wspierającej i generuje procedury get/set.

Na przykład:

class foo { 

public int myInt; 

public int MyInt { get { return myInt;} 
        set { myInt = value;} } 

} 

vs

class foo { 

public int MyInt { get; set; } 

} 

W tym przypadku nie jest niejednoznaczny w wszystko co staramy się robić, co kompilator może pomóc i automatycznego generowania jako niezbędne.

Jeśli musisz zaimplementować niestandardową funkcję ustawiającą/pobierającą, która obejmuje także ustawianie wartości, musisz użyć klasy uczącej, jak pokazano w drugim przykładzie.

3

Drugi blok kodu, który podałeś, jest tak bliski "poprawnego" sposobu implementacji nietrywialnych (z logiką) właściwości w języku C#, o czym jestem świadomy.

1
  • przedmiot

Wracasz nieruchomość, która będzie chodzić do get ponownie. Czy ta właściwość ma pole zaplecza?

Twój proponowany sposób jest poprawny. Ideą właściwości jest jedynie syntaktyczny cukier nad metodami get i set, a nie usuwanie potrzeby lokalnego pola. Auto-właściwości to cukier syntaktyczny, ale w tym przypadku nie można zapewnić implementacji.

Co może być myślenie o to auto właściwość:

public string MyName { get; set; } 

Ale dla nich nie można realizować pobrać lub ustawić.

Ponadto, jeśli świadczą nietrywialne realizacji na nieruchomości należy pamiętać, że istnieje kilka wytycznych:

  • Do pobierania i ustawiania działania powinny być lekkie, czyli szybko.
  • Wartość zwracana właściwości nie powinna zmieniać się między wywołaniami, chyba że jest ustawiona na inną wartość (tj. Jeśli stan klasy wewnętrznie powoduje inną wartość, zaleca się użycie metody zamiast zwracania wartości).
+0

Huh, rozumiem. Pomyślałem, że robienie tego w ten sposób pośrednio tworzy pole wsparcia gdzieś wzdłuż linii. – Oliver

+0

@Oliver pola są tworzone niejawnie tylko w przypadku właściwości auto. –

+0

Niekoniecznie chcesz, aby automatycznie generował pole w tle. Na przykład przy dziedziczeniu z interfejsu: 'bool SupportsSomeProperty {get {return true; }} ' – climbage

6

Kiedy używasz gettera w ten sposób, musisz również ręcznie dodać pole, jakie masz w swoim drugim przykładzie.

Nie można po prostu odwołać się do tej samej właściwości, co w pierwszym przykładzie.

Podajesz skrót syntaktyczny, ale nie używasz skrótu, o ile wiem.

Skrót dla właściwości, gdy operacja nie jest wykonywana na zmiennej zanim powrócił byłoby:

public string pageTitle{get;set;} 

To automatycznie tworzy pole oporowe dla Ciebie.

1

"Skrót syntaktyczny" niekoniecznie musi być skrótem syntaktycznym. Jeśli chcesz użyć właściwości automatycznych, możesz użyć publicznej nazwy String String {get; zestaw; }

i wszystko dla ciebie, w tym pole zaplecza. Prawdziwym celem właściwości jest ukrycie pola zaplecza przed implementatorami ... OOP, abstrakcja i dziedziczenie i wszystkie te rzeczy. Za pomocą właściwości można dodać sprawdzanie poprawności lub zmienić format zwracania bez konieczności wyszukiwania każdego wystąpienia dostępu do pola kopii.

1

Ponadto, właściwości (składnia get i set) zwykle mają PascalCase, tj. PageTitle.

+0

Dzięki. Pochodzę z tła Java, które używa różnych konwencji. Mój schemat nazewnictwa jest w tej chwili dość chaotyczny. – Oliver

+0

To zrozumiałe. Pochodzę też z Jawy. Konwencja C# może czasami być bardzo dziwna. W zeszłym tygodniu napisałem coś takiego: Fixation.Fixation Fixation = new Fixation() Może nie jest to najlepszy wybór nazwy, ale ma więcej sensu poza klasą, więc utknąłem z nią. –