Akcesory get i set

0

Witam serdecznie. Na zajęciach napisaliśmy program, ale nie potrafię zrozumieć po co zmiennej stawka dawać właściwość get i set. Program działa identycznie mimo zmiany:

  public double stawka { get; set; };

na
public double stawka;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{

    class Pracownik
    {
        string imie, nazwisko;
        int godziny; //z dokładnością do godziny
      public double stawka; //właściwość

        //Konstruktor publiczny, ładujący, nawet nie piszemy void
        public Pracownik(string i, string n, double s, int g)
        {
            imie = i;
            nazwisko = n;
            stawka = s;
            godziny = g;
        }

        //Metoda drukuj w jednej linii, nie zwraca jednej konkretnej wartości więc void
        public void drukuj()
        {
            Console.WriteLine("{0,8}{1,12}{2,8}{3,8}{4,8}", imie, nazwisko, stawka, godziny, stawka * godziny);//stawka * godziny - liczba zasadnicza
        }

    }
    class Program
    {
        static void Main(string[] args)
        {
            Pracownik p1 = new Pracownik("jan", "Kowalski", 25.0, 130); // wykorzystuję stworzony konstruktor do ładowania różnych danych za jednym razem.
            p1.drukuj();
            p1.stawka = 26.50; // W tej linii urochomi się właściwość stawka{set}
            p1.drukuj();
            Console.WriteLine(p1.stawka);// W tym miejscu urchomi się właściwość stawka{get}
            Console.ReadKey();
        }
    }
}
2

Po pierwsze, nazwy właściwości piszemy wielką literą.

A teraz odpowiadając na pytanie - gdy później dojdziesz do wniosku, że stawka nie może być mniejsza niż 20, to napiszesz sobie tak:

private double stawka;  // pole prywatne
public double Stawka     // właściwość
{
    get { return this.stawka; }
    set 
    { 
         if (value < 20)
              this.stawka = 20;
         else 
              this.stawka = value;
    }
}

i nie będziesz musiał przerabiać wszystkich klas, które wcześniej odwoływały się do pola, a teraz zamiast niego jest właściwość.

0

ale nie potrafię zrozumieć po co zmiennej stawka dawać właściwość get i set.
Bo dla niektórych publiczne pole jest niekoszerne.
Trywialna właściwość natomiast, robiąca dokładnie to samo, z jakiegoś powodu jest już OK ;-)

To przesąd taki, ewentualnie wierzenie religijne, możesz się do tego stosować albo nie.
Próba dyskusji rozpocznie tylko flejma.

Natomiast ma to znaczenie dla mechanizmu refleksji – np. przy różnych data binding i podobnych cudach na kiju, często środowisko szuka publicznych właściwości a olewa pola.

0

@Azarien, przy zmianie pola na właściwość musisz przekompilować wszystkie projekty wykorzystujące to pole.
Właściwości łatwiej się też debuguje.
No, a poza tym, to po co w ogóle jakieś zasady, piszmy wszystko static i nie będziemy mieli żadnych problemów.

0

To po co ta dowolność? niech kompilator zgłasza zostawienie "gołego" publicznego pola jako błąd. Dla mnie osobiście to też niepotrzebna redundancja kodu sztucznie promowana przez purystów językowych, ale w dobie automatycznego wykańczania kodu jakoś nie stanowi to większego problemu. Bardziej cieszyłbym się gdyby kod się nie kompilował jeśli nie jest formatowany odpowiednio.

1

Ja się jakoś po prostu przyzwyczaiłem po latach pracy z .NET. Publiczne pola w intelisense po prostu kłują po oczach ;)

1

Skoro to to samo, to zróbcie wirtualne pole.

1

Ogółem używając publicznych pól naruszasz enkapsulację. Pola te powinny być dostępne i modyfikowane jedynie z poziomu klasy czyli przez metody albo konstruktory.
Jak pewnie wiesz język C# kompilowany jest najpierw do tzw. kodu CIL:
http://pl.wikipedia.org/wiki/Common_Intermediate_Language

Tworząc właściwości automatyczne czyli np:

public string FirstName {get; set;}

Łączysz tak naprawdę przyjemne z pożytecznym bo: pisze Ci się wygodnie i szybko (tak samo jak pole), masz do tego dostęp tak jak do publicznego pola ale kompilator i tak w kodzie CIL utworzy sobie osobne metody typu:

public void GetName(){}
public void SetName(){}

a pola oznaczy sobie jako prywatne.
Więcej na ten temat znajdziesz tutaj:
http://msdn.microsoft.com/en-us/library/aa288470(v=vs.71).aspx

1

I jeszcze jedna drobna korzyść. Można w bardzo prosty i przyjemny sposób określić prywatny dostęp do zapisu publicznej właściwości:

public int MyProperty {get; private set;}
1
Azarien napisał(a):

ale nie potrafię zrozumieć po co zmiennej stawka dawać właściwość get i set.
Bo dla niektórych publiczne pole jest niekoszerne.
Trywialna właściwość natomiast, robiąca dokładnie to samo, z jakiegoś powodu jest już OK ;-)

Z własnego doświadczenia widzę, że publiczne pole, przy przypisywaniu do niej wartości poza klasą w której jest zadeklarowane, może prowokować do sprawdzenia warunku dla przypisywanej tej wartosci właśnie poza klasą (czyli w innej klasie).
Potem rozwijając jakiś projekt powiela się, albo rozszerza sprawdzanie przypisywanej wartości dla takiego pola publicznego w kilku innych klasach, czyli za przypisanie jakiejś wartości do pola publicznego odpowiada już pare różnych klas - po kilku zmianach, przeróbkach, udoskonaleniach projektu - człowiek dochodzi do wniosku że jednak sprawdzanie zakresu, warunków dla przypisania wartości do tego pola, powinna odpowiadać tylko ta klasa w której to pole jest zadeklarowane i teraz:

  • przerabiamy to pole na właściwość z rozbudowanym akscesorem set;
  • szukamy we wszystkich klasach gdzie sprawdzaliśmy warunki przed przypisaniem wartości do tego pola, kasujemy te warunki i pewnie powiązane z nimi metody i zmieniamy tylko na przypisanie wartości
  • po kolejnej kompilacji, modlimy się żeby już nigdzie nie zostawić śmieci po takiej przróbce i żeby z czasem nie zaczęło bruździć nie wiadomo skąd i co ;)

Także podsumowując, gdyby na samym początku projektu zadeklarować trywialną właściwość

public double Stawka { get; set; }

byłoby znacznie wyższe prawdopodobieństwo na to, że unikniemy wyciągania sprawdzeń przypisania wartości do innych klas i zaczniemy od razu kombinować w akcesorze set; co pozwoliłoby uniknąć rozciągania odpwoiedzialności za ustawienie tego pola do kilku różnych klas.

Jestem za tym aby nie wymyślać na nowo koła, i skoro wielu doświadczonych mówi aby czegoś używać, to tego używać zgodnei z ich wskazówkami, trzeba korzystać z wiedzy bardziej doświadczonych, można dzięki temu uniknąć straty czasu poświęconego na rozgrzebywanie tematu i dochodzenie do identycznych wniosków jak te wcześniej podane na tacy ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1