Do czego służą akcesory w c#?

0

Chodzi o cos takiego:

Zalozmy ze mamy klase, dokladnie chodzi o akcesory get,set i zapis tego. Wiem ze nasze setNazwa get Nazwa mozna ograniczyc do

protected string nazwa { get; set; }


class Owoc
{
  protected string nazwa;
  protected int waga;
  protected int cena;
 
  public Owoc() { }
  public Owoc(string nazwa, int waga, int cena)
  {
    this.nazwa = nazwa;
    this.waga = waga;
    this.cena = cena;
  }
  public void setNazwa(string nazwa)
  {
    this.nazwa = nazwa;
  }
  public string getNazwa()
  {
    return nazwa;
  }
 
  public static int podajKoszt(Owoc A, Owoc B)
  {
    return A.cena + B.cena;
  }
}

ale o ile to co w code wykonamy sobie np tak:

 Jabłko A = new Jabłko("Antonówka", 10, 2, "czerwone", "letnia");
 A.setNazwa("zwyczajna");

w ogóle jak ktos bardziej zorientowany jest moglby wytlumaczyc jak to dziala, bylbym wdzieczny.

Caly kod dostepny jest na:

http://marie-www.ee.pw.edu.pl/~cackoa/courses/jimp/jimp13.php

zadanie1 na dole strony robilem sobie to tak.. zeby sie czegos nauczyc.. jesli to jakas reklama to niech mod skasuje ten link

0

public int A { get; set; } kompilator zamienia na:

private int _a;
public int GetA() {
  return _a;
}

public void SetA(int value) {
  _a = value;
}
0

A jakie jest pytanie?

0

w skrócie, dzięki właściwościom i akcesorom get i set uzyskujemy dostęp do prywatnych pól w klasie. Get pobiera wartość , set nadaje wartość value.

0

Akcesory w najprostszej formie wyglądają tak jak podałeś, czyli prosta operacja przypisania / pobrania wartości. W tak prostych przykładach nie ma to oczywiście sensu ponieważ można to zrobić bez akcesorów, czyli odwoływać się bezpośrednio do pól klasy i będzie szybciej. Sytuacja jednak się zmienia, gdy w polach klasy mają być przechowywane wartości z jakiegoś przedziału (np oceny), inne pola powinny zmienić wartość w zależności od nowej wartości, czy też trzeba wykonać jakąś inną dodatkową operację.
Przykładowo podając ocenę należy sprawdzić czy mieści się w przedziale 1-6 i w przypadku, gdy tak nie jest wykonać odpowiednią akcję. To samo jest w przypadku pobierania wartości. Przed jej pobraniem może być konieczne wykonanie jakiejś dodatkowej operacji.
Do tego właśnie stosuje się akcesory, żeby mieć kontrolę nad tym co jest przekazywane do klasy i co ona zwraca.

0
freemp3 napisał(a):

W tak prostych przykładach nie ma to oczywiście sensu ponieważ można to zrobić bez akcesorów, czyli odwoływać się bezpośrednio do pól klasy i będzie szybciej.

A hermetyzacja?

0

No tak, dochodzi jeszcze kwestia hermetyzacji. Oczywiście zgodnie z dobrymi praktykami powinno się ukryć wszystkie pola klasy i dodać im odpowiednie akcesory, co nie zmienia faktu, że bezpośrednie odwołanie jest szybsze ;) Jednak w przypadku późniejszych modyfikacji i nałożenia jakichś ograniczeń na któreś z pól klasy bezpośrednie odwołanie jest już problemem. Dlatego stosowanie akcesorów jest lepszym rozwiązaniem.

1

co to za hermetyzacja jak do kazdego pola masz dostep? (tak poprzez funkcje, ale jezeli funkcja nic nie robi to po co ta nadproduktywna funkcja?)

0
freemp3 napisał(a):

co nie zmienia faktu, że bezpośrednie odwołanie jest szybsze ;)

O ile szybsze?

fasadin napisał(a):

jezeli funkcja nic nie robi to po co ta nadproduktywna funkcja?

  1. Żeby działało np. bindowanie.
  2. Żeby można było używać masy bibliotek, które korzystają z właściwości.
  3. Żeby nie wprowadzać breaking change, gdy jednak będziemy potrzebowali właściwości, a nie nie pola.
3

w C# jest to o tyle dobrze rozwiązane, że można napisać:

public string nazwa { get; set; }

i zachowuje się to jak normalne pole:

nazwa = "Ala ma kota";
Console.WriteLine(nazwa);

a jak chcemy dodać do tego jakąś inną akcję, po prostu rozwijamy akcesory:

private string _nazwa;
public string nazwa
{
    get
    {
        JakaśInnaAkcja();
        return _nazwa;
    }
    set
    {
        JakaśInnaAkcja();
        _nazwa = value;
    }
}

i mamy dowolny dodatkowy kod, a w miejscu wywołania nic się nie zmienia.

Dlatego nie ma sensu w C# pisanie trywialnych funkcji getCośtam() i setCośtam() które nic więcej nie robią jak tylko odczytują i zapisują pole, bo można to uzyskać poprzez właściwość (property) z domyślnymi akcesorami { get; set; }, albo po prostu publiczne pole, które jak będzie trzeba to się przerobi na właściwość.

PS. get i set mogą mieć różny poziom dostępu, na przykład:

public string nazwa { get; protected set; }

taką właściwość da się z zewnątrz klasy tylko odczytać, ale zapis musi być w tej klasie - albo klasie potomnej.

0

ok no ale zalozmy ze mam

public string nazwa { get; set; }

czyli taki akcesor ustawiony na public w jakiejs klasie Pies np..
jak teraz tego uzyc tworzac dwa psy jakis tam rasowy , kundel i nadajac im nazwy uzywajac tego akcesora
tworzyc klasy bedziemy tworzyc za pomoca dziedziczenia.. a jak wywolac ten akcesor i jak to dziala na takim przykladzie np..

i co by bylo gdyby nasz akcesor byl prywatny

private string nazwa { get; set; }

moze ten pierwszy przyklad nie ilustrowal o co mi chodzi dokladnie ..

a pytanie jest caly czas to samo jak to dziala i do czego to sluzy?

3

To po kolei.

To jest pole:

private string nazwa;

Takie pole można opakować we właściwość:

public string Nazwa
{
    get { return this.nazwa; }
    set { this.nazwa = value; }
}

Właściwość to właściwie metoda dająca dostęp do pola. Jej użycie jest po prostu ładniejsze i czytelniejsze niż wywoływanie zwykłej metody.
get i set to akcesory. get zwraca wartość, set ustawia wartość. Właściwość może mieć jeden albo oba akcesory.

W akcesorach można mieć też bardziej skomplikowaną logikę, np. jakąś walidację:

public string Nazwa
{
    get { return this.nazwa; }
    set 
    { 
         if (value == "Stefan") throw new ArgumentException("Stefan to zła nazwa!");

         this.nazwa = value; 
    }
}

Ale dla najprostszego przypadku, czyli wyłącznie ustawiania i pobierania wartości pola, pisanie zawsze takiego kodu:

private string nazwa;

public string Nazwa
{
    get { return this.nazwa; }
    set { this.nazwa = value; }
}

jest bardzo żmudne, dlatego dawno temu (jakieś 8 lat) wprowadzono do C# właściwości automatyczne, czyli:

public string Nazwa { get; set; }

Oba powyższe kody są sobie równoważne, ten drugi jest po prostu krótszy.

Jak się tego używa? Bardzo prosto:

Pies p1 = new Pies();
p1.Nazwa = "Kundel";

Co by było, gdyby utworzyć właściwość z dwoma prywatnymi akcesorami? Nic szczególnego, po prostu byłaby ona dostępna jedynie wewnątrz klasy, więc właściwie nie miałaby sensu. W takiej sytuacji lepiej użyć zwykłego pola.

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