Wątek przeniesiony 2014-09-01 15:34 z C# i .NET przez somekind.

Jaki cel mają properties w C#?

0

Jestem programistą C++, w międzyczasie przebiło się kilka projektów większych i mniejszych w Javie, ale w przeciwieństwie do C++ nie mogę o Javie powiedzieć żebym ją znał. W C# nie pisałem nic poza jakimiś zadaniami ze SPOJ itp. czyli generalnie języka nie znam w ogóle ponad poziom pisania w Javie/C++ z nadzieją że zadziała.
Do rzeczy, coś co mnie od jakiegoś czasu zastanawia. Co jest takiego... super w properties (właściwościach? nie wiem, czy to powinno się (tak) tłumaczyć) w C#. Dają one "przezroczystość" stosowania zmiennych prywatnych, ale... czy nie chodzi o to, żeby tej przezroczystości nie było? Czy nie po to pole jest prywatne, żeby... nie było do niego dostępu z zewnątrz? Zwykły getter, setter niejako gwarantuje "zastanowienie się" w momencie ustawiania jakiejś wartości.
Więc... po co?
Czytałem trochę na stacku, ale... bardziej skupiają się tam w czym lepsze są properies od publicznych pól, a mnie zastanawia to dlaczego to w ogóle istnieje.

0

Pole to tylko pole - bezpośrednio piszesz i/lub czytasz. W propertisach możesz zawrzeć dodatkową logikę do przekazywanych/odczytywanych wartości.

0

Zamiast tworzyć prywatną zmienną i do tego dwie metody (get i set), to wystarczy, że stworzyć properties:

public int Varriable { get; set; }

Zarówno get jak i set mogą mieć logikę.

dodanie znacznika <code class="csharp"> - furious programming

0

Zwykły getter, setter niejako gwarantuje "zastanowienie się" w momencie ustawiania jakiejś wartości.

To jest właśnie zamiast gettera i settera.

np:

class Rectangle
{
     public int A {get;set;}
     public int B {get;set;}
     public int Perimeter
    {
        get { return 2*(A+B);}
    }
}
0
dam1an napisał(a):

To jest właśnie zamiast gettera i settera.

Dobra, przypuśćmy, że załapałem, chociaż moim zdaniem nadal bezpieczniejsze i bardziej czytelne są zwykłe gettery settery, ale mniejsza z tym - ile osób tyle zdać, więc nie ma sensu w to dalej iść.

Jedno pytanie jeszcze tak na szybko - getter musi otrzymać swój typ? czy można mu przekazać coś innego i "obsłużyć"?

0

Nie, nie możesz mieć właściwości typu int i przekazać mu obiekt typu Car.

moim zdaniem nadal bezpieczniejsze i bardziej czytelne są zwykłe gettery settery

public int A {get;set;}

lub

private int a;

void SetA(int a)
{ 
    this.a = a;
}

int GetA()
{
    return a;
}

Serio, wolisz druga wersje?

0

A niby jakim cudem zwykłe gettery i settery sa bezpieczniejsze? O.o

0
someONE1 napisał(a):

A niby jakim cudem zwykłe gettery i settery sa bezpieczniejsze? O.o

Bo zapewniają, że nie zrobi się czegoś w stylu obiekt.pole = 10;
jednak napisanie obiekt.setPole(10) włącza myślenie, przynajmniej u mnie

dodanie znaczników `` - furious programming

0
dam1an napisał(a):

Nie, nie możesz mieć właściwości typu int i przekazać mu obiekt typu Car.

moim zdaniem nadal bezpieczniejsze i bardziej czytelne są zwykłe gettery settery

public int A {get;set;}

lub

private int a;

void SetA(int a)
{ 
    this.a = a;
}

int GetA()
{
    return a;
}

Serio, wolisz druga wersje?

Wolałbym pierwszą gdyby nie pozwalała na przezroczystość odwołań do zmiennej, tylko tworzyła automatycznie metody, przez które mam się odwoływać.
ale tak jak już pisałem, ile ludzi tyle opinii, więc pewnie milion osób woli takie rozwiązanie jakie jest

0

Nie odwołujesz się bezpośrednio do zmiennej. W takiej sytuacji public int A {get;set;} kompilator sam sobie przerabia kod na coś takiego:

private int a;
public int A 
{
    get {return a;}
    set {a = value;}
}

I samemu też w każdej chwili możesz przerobić właściwość jeśli w którymś momencie stwierdzisz że public int A {get;set;} nie wystarczy.

0
templas napisał(a):
someONE1 napisał(a):

A niby jakim cudem zwykłe gettery i settery sa bezpieczniejsze? O.o

Bo zapewniają, że nie zrobi się czegoś w stylu obiekt.pole = 10;
jednak napisanie obiekt.setPole(10) włącza myślenie, przynajmniej u mnie

Ale właśnie dzięki takim właściwościom możesz korzystać z nich jak ze zmiennej publicznej pisząc obiekt.pole tylko, że pod tym ukryta jest logika...

No i co do nastepnej wypowedzi to przecież nie odwołujesz sie bezpośrednio bo we właściwości możesz zawrzeć logikę

0

Ok, chyba zostałem przekonany

0

W treściwych angielskich słowach, chodzi o uniform access principle (pol. zasadę jednolitego dostępu).

0

No chyba nie, bo settery i gettery znane np. z C++ też się pod tym względem sprawdzają

usunięcie cytowania całego poprzedniego posta - furious programming

0

No ale przecież gettery i settery maja IDENTYCZNĄ funkcjonalność. Właściwości w C# to jedynie skrócenie zapisu.

usunięcie cytowania całego poprzedniego posta - furious programming

0

No ok, w moim poście chodziło mi o to, że właściwości nie mają tej przewagi nad setterami/getterami znanymi np. z C++, choć jak teraz myślę, to może @winerfresh nie miał tego na myśli. To był cel mojego tematu i może z tego powodu spojrzałem na to przez taki pryzmat.

W każdym razie podsumowując... chodzi tylko o wygodę? Innych różnic nie ma?

usunięcie cytowania całego poprzedniego posta - furious programming

0

Jaką przewagę mają twoim zdaniem gettery i settery nad właściwościami?

0

Bo ty zadałeś pytanie czy jest sens robić pole prywatne, a następnie gołe settery i gettery do niego. Odpowiedź jest prosta: nie ma sensu, bo zmienna w takim razie powinno być publiczne. Chodzi jednak o coś innego, w czasie jak rozwijasz swój kod może się zdarzyć, że zmienna, która do tej pory była publiczna nagle takową być przestaje no i pojawia się problem. Jak rozwiązać niekompatybilność wsteczną? I tutaj właśnie wkracza UAP - jeśli nie ma różnicy między dostępem przez getter/setter a dostępem do pola publicznego, to możesz takie zmiany wprowadzać bez uszczerbku na interfejsach.

0

Jeśli robisz samego settera (bez gettera) to wtedy wg. mnie czytelniej jest nie używać properties tylko SetXXX(value)

0

W takiej sytuacji public int A {get;set;} kompilator sam sobie przerabia kod na coś takiego:

W praktyce to przerobi na coś takiego:

public int A;

bo nie ma sensu generować metod jak to jest tylko pole.
(ewentualnie można to sobie tłumaczyć że zinline'uje gettera i settera, co na jedno wychodzi)

Różnica między parą funkcji GetCośtam i SetCośtam a właściwością Cośtam jest tylko w użyciu: pierwsze to zwykłe metody, drugie udaje że jest polem.

0

praktycznie to jest to samo co Get/Set. Kod wyglada lepiej dzieki properties. Delphi tez to ma ;)

0

To ja się dołączę do tematu, bo mam podobne wątpliwości.
Czytałem, że ze względu na hermetyzację wszystkie (większość) pól powinno być prywatnych, a dostęp do nich (jeśli potrzebny) powinien odbywać się przez properties. Autor dodał jeszcze (o ile dobrze pamiętam), że powinno tak być ze względu na bezpieczeństwo.
I tutaj moje pytanie: w jaki sposób niby kod:

public int A {get; set;} 

jest bardziej bezpieczny/ lepszy od:

public int A;

?
Mimo, że wiem co się dzieje "pod spodem", dla mnie to tylko dwa słowa więcej, a funkcjonalność kodu taka sama. Nie widzę gdzie kryje się to niebezpieczeństwo w używaniu publicznych pól.

1
paulonio napisał(a):

I tutaj moje pytanie: w jaki sposób niby kod:

public int A {get; set;} 

jest bardziej bezpieczny/ lepszy od:

public int A;

?

zmiennych nie możesz zawrzeć w interfejsie, property możesz
interfejs może być zdefiniowany nawet w klasie pochodnej - jeżeli nie możemy dotknąć klasy nadrzędnej (bo na przykład pochodzi z zewnętrznej dll-ki) to nie będziemy mieli szansy dodać tej zmiennej do interfejsu

tak samo gettery, settery możesz przeciążać (setter może być wirtualny i różny w klasie pochodnej)

w get, set możesz też wpisać typ dostępu - najczęściej setter jest private lub protected
ogólnie przez enkapsulację nie daje się dostępu read/write do każdej zmiennej w klasie - zazwyczaj wtedy klasa traci sens.
Logika klasy a więc i wartość jej pół powinna być w większości kontrolowana wewnątrz klasy przez jej metody dostępowe - tak więc większość właściwości zazwyczaj wygląda w ten sposób:

public int A [get; private set; }

a tego nie zamienisz już na zwykłą zmienną

0

Stosunkowo niedawno byl juz wątek typu publiczne pola vs properties, poruszane byly te same kwestie i temat zostal wyczerpany.
Niestety nie moge znalezc tego wątku, moze ktos inny zapoda link.

1

Wczoraj na początku tego tematu napisałem coś takiego:

class Rectangle
{
     public int A {get;set;}
     public int B {get;set;}
     public int Perimeter
    {
        get { return 2*(A+B);}
    }
}

Jednak po jakimś czasie zauważyłem że przecież boki prostokąta nie mogą być ujemne, zmieniam:

class Rectangle
{
     private int a;
     public int A 
     {
          get {return a;}
          set {a = value >= 0 ? value : 0;}
     }
     private int b;
     public int B 
     {
          get {return b;}
          set {b = value >= 0 ? value : 0;}
     }

     public int Perimeter
    {
        get { return 2*(A+B);}
    }
}

I jeśli przez ten czas używałem tej klasy 20 razy w kodzie to to nadal będzie działać, gdybym używał zamiast tego pól publicznych to trzeba by sporo zmieniać.

0

@dam1an: pytanie czy w takim przypadku nie lepiej byłoby rzucać wyjątku? Moim zdaniem lepiej bo jeżeli ktoś użyje tego property z ujemną wartością to użyje go w sposób nieprawidłowy i powinno to być jakoś zasygnalizowane.

To troche tak jakbyś miał tablice i po przekroczeniu indeksu otrzymałbyś wartość ostatniego elemenu. Program się co prawda dzięki temu nie wywali, ale jak będziesz tworzył jakiś algorytm to w razie ewentualnych pomyłek dziwił się będziesz dlaczego np. czasami wyniki obliczeń są nieprawidłowe a czasami prawidłowe - prawidłowe mogą być w sytuacji kiedy nie wykraczasz poza zakres tablicy, a nieprawidłowe kiedy z jakiś powodów wykraczasz.

Jak dostaniesz wyjątek to sprawa jest oczywista - od razu wiesz co jest przyczyną, że coś nie działa i w którym miejscu jest błąd. Dlatego użycie wyjątków wydaje mi się lepszym rozwiązaniem.

Tak w ogóle to czy prostokąt może mieć zerowe długości boków? :) Wydawało mi się, że nie, ale pewny nie jestem.

0

Można wyrzucić wyjątki, można ustawić minimalną jak i maksymalną wartość jaką ma przyjmować twój prostokąt, jak chcesz. Chodziło mi o pokazanie o co chodzi z properties.

0

Ok. rozumiem wasze argumenty, ale nie do końca wyjaśniają moje wątpliwości. Przytoczę więc cytat, z którego one wynikają (pochodzi z A. Troelsen "Pro C# 5 and the .NET Framework 4.5"):

Closely related to the notion of encapsulating programming logic is the idea of data protection. Ideally, an object’s state data should be specified using the private (or possibly protected) keyword. In this way, the outside world must ask politely in order to change or obtain the underlying value. This is a good thing, as publicly declared data points can easily become corrupted (hopefully by accident rather than intent!).

Zatem w jaki sposób konstrukcja:

public int A {get; set;}

chroni potencjalnie nasze dane bardziej niż zwykłe publiczne pole skoro dla "świata zewnętrznego" obie konstrukcje zachowują się podobnie ?

0
paulonio napisał(a):

Zatem w jaki sposób konstrukcja:

public int A {get; set;}

chroni potencjalnie nasze dane bardziej niż zwykłe publiczne pole skoro dla "świata zewnętrznego" obie konstrukcje zachowują się podobnie ?

Taka chroni nieco bardziej, i łatwo do niej "przejść w razie czego":

public int A { get; private set; } 
0

(or possibly protected)

Kompletnie bezsensu. Osoba dziedziczaca jest takim samym szkodnikiem jak kazdy inny uzytkownik klasy i nie powinien miec dostepu bezposredniego, jesli cos ma byc rzeczywiscie chronione.

chroni potencjalnie nasze dane bardziej niż zwykłe publiczne pole skoro dla "świata zewnętrznego" obie konstrukcje zachowują się podobnie ?

Nie chroni w ogole. Natomiast umozliwia latwiejsza zmiane w wypadku, gdy chronienie okaze sie potrzebne.

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