Zamiana właściwości z poziomu innej właściwości. Czy tak można?

0

Cześć, mam takie pytanie, czy dobrym postępowaniem jest zmiana właściwości za pomocą innej właściwości? Może kawałek kodu dla rozjaśnienia o co mi chodzi:

class Cena
    {
        private decimal cenaNetto;
        private decimal cenaBrutto;

        public decimal CenaNetto
        {
            get { return cenaNetto; }
            set { 
                cenaNetto = value;
                CenaBrutto = value * 1.23m; //czy to dobra praktyka?
            }
        }
        public decimal CenaBrutto
        {
            get { return cenaBrutto; }
            set { cenaBrutto = value; }
        }

        //...
    }
 

Chodzi o linijkę z komentarzem, czy tak się robi, czy należy postąpić jakoś inaczej?

0

Oprócz tego, że Ci się mieszają wielkości liter to osobiście nie widzę w tym nic złego.

3

Możesz tak zrobić, ale musisz też zachować jakąś konsekwencję w tym co robisz. Usuń tego set-a CenaBrutto. Najlepiej zostaw sobie tylko i wyłącznie zmienną cenaNetto oraz vat. CenaBrutto będzie obliczana na żądanie (np. w ramach get-a).

0
Cennik napisał(a):

Najlepiej zostaw sobie tylko i wyłącznie zmienną cenaNetto oraz vat. CenaBrutto będzie obliczana na żądanie (np. w ramach get-a).

Ale co w tym jest najlepszego, bo nie rozumiem? Jeśli towar ma znaną cenę netto i znaną wartość VAT, to cenę brutto wystarczy obliczyć jednokrotnie, podczas tworzenia obiektu, a nie miliard razy przy każdym odwołaniu. Ja wiem, że może to nie jest krytyczne z punktu widzenia wydajności, ale obliczanie za każdym razem jest po prostu brzydkie.

0
somekind napisał(a):
Cennik napisał(a):

Najlepiej zostaw sobie tylko i wyłącznie zmienną cenaNetto oraz vat. CenaBrutto będzie obliczana na żądanie (np. w ramach get-a).

Ale co w tym jest najlepszego, bo nie rozumiem? Jeśli towar ma znaną cenę netto i znaną wartość VAT, to cenę brutto wystarczy obliczyć jednokrotnie, podczas tworzenia obiektu, a nie miliard razy przy każdym odwołaniu. Ja wiem, że może to nie jest krytyczne z punktu widzenia wydajności, ale obliczanie za każdym razem jest po prostu brzydkie.

Cennik dobrze goda
operowanie tylko na jednej zmiennej skoro ta druga jest tylko przeskalowaną pierwszą będzie lepsze bo jest mniejsze prawdopodobieństwo pomyłki
w tym kodzie trzeba uważać na to żeby cały czas wewnątrz klasy operować na CenaNetto, a nie cenaNetto - taka pomyłka będzie dopuszczalna, bardzo łatwa do popełnienia (wystarczy nie docisnąć dobrze shift) i trudna do wykrycia
poza tym musisz pamiętać żeby to działało obustronnie - jeżeli ustalając CenaNetto, automatycznie zmienia się CenaBrutto to zmieniając CenaBrutto (skoro dajesz taką możliwość) powinna się zmieniać CenaNetto

tak więc jeżeli chcesz sobie zaoszczędzić czasem nawet godzin ślęczenia nad kodem żeby znaleźć błąd "choć wszystko wygląda ok" to lepiej nie dopuszczaj do takich sytuacji
no chyba że to bardzo krótka klasa, tak jak przedstawiona tutaj

i bez przesady - dodanie prostego *1.23 do gettera to nic w porównaniu do ilości instrukcji które procesor i tak musi wykonać żeby się dobrać do gettera
gettery i settery z natury coś robią poza zwykłym przekazaniem wartości - jeśli chcesz mieć coś obliczone raz to wynik przepisujesz do zmiennej
a skoro wszystkie wartości miałaby wyglądać tylko tak

public decimal CenaBrutto
        {
            get { return cenaBrutto; }
            set { cenaBrutto = value; }
        }

to po co w ogóle to robić? nie lepiej upublicznić cenaBrutto?

1

to po co w ogóle to robić? nie lepiej upublicznić cenaBrutto?
Dla niektórych publiczne pola są niekoszerne. Argumenty że trywialna właściwość jest w zasadzie tym samym nie docierają. Dyskusja jest daremna.

Powyższe można przepisać też tak:

public decimal CenaBrutto { get; set; }

a w połączeniu z cenąNetto tak:

public decimal CenaNetto { get; set; }
public decimal CenaBrutto
{
    get { return CenaNetto * VAT; }
    set { CenaNetto = value / VAT; }
}

dzięki czemu pola prywatne nie istnieją, i nie można się pomylić.

0
unikalna_nazwa napisał(a):

w tym kodzie trzeba uważać na to żeby cały czas wewnątrz klasy operować na CenaNetto, a nie cenaNetto - taka pomyłka będzie dopuszczalna, bardzo łatwa do popełnienia (wystarczy nie docisnąć dobrze shift) i trudna do wykrycia

Ale co z tego? O testach jednostkowych słyszałeś?

poza tym musisz pamiętać żeby to działało obustronnie - jeżeli ustalając CenaNetto, automatycznie zmienia się CenaBrutto to zmieniając CenaBrutto (skoro dajesz taką możliwość) powinna się zmieniać CenaNetto

Ja tu nic o obustronnym nie pisałem, tylko o obliczeniu ceny brutto na podstawie ceny netto.
Ale nawet jeśli trzeba robić także odwrotnie, to co za problem? Programiści chyba są od myślenia, pamiętania i uważania.

tak więc jeżeli chcesz sobie zaoszczędzić czasem nawet godzin ślęczenia nad kodem żeby znaleźć błąd "choć wszystko wygląda ok" to lepiej nie dopuszczaj do takich sytuacji

Chyba już znam odpowiedź na pytanie o testach jednostkowych.

to po co w ogóle to robić? nie lepiej upublicznić cenaBrutto?

A nie lepiej zrobić autoimplementujące właściwości? Przynajmniej będą się ładnie bindowały.

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