Akcesory get i set (przykład z książki Head First C#)

0

Witam!
Przerabiam właśnie książkę Head First C# a dokładnie ćwiczenie dotyczące hermetyzacji i akcesorów get oraz set.
W całym programie chodzi o to, żeby poprawnie obliczało mi liczbę jedzenia dla krów (BagsOfFeed) przy danej ich ilości (numberOfCows) i zapotrzebowaniu jednej krowy (feedMultiplier).

Program działający wygląda tak:

Część formularza Form1:

 Farmer farmer;
        public Form1()
        {
            InitializeComponent();
            farmer = new Farmer(15, 30);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Console.WriteLine("Potrzebuję {0} worków paszy do wykarmienia {1} krów", farmer.BagsOfFeed, farmer.NumberOfCows);
        }

        private void CowAmount_ValueChanged(object sender, EventArgs e)
        {
            farmer.NumberOfCows = (int)CowAmount.Value;
        }

Klasa Farmer

class Farmer
    {
        public int BagsOfFeed { get; private set; }

        private int feedMultiplier;
        public int FeedMultiplier { get { return feedMultiplier; } }

        public Farmer(int numberOfCows, int feedMultiplier)
        {
            this.feedMultiplier = feedMultiplier;
            NumberOfCows = numberOfCows;
        }

        private int numberOfCows;
        public int NumberOfCows
        {
            get
            {
                return numberOfCows;
            }
            set
            {
                numberOfCows = value;
                BagsOfFeed = numberOfCows * FeedMultiplier;
            }
        }
    }

Zastanawia mnie dlaczego inaczej ustawiana jest wartość numberOfCows a inaczej foodMultiplier skoro obie wartości są inicjowane przez konstruktur?

Czy taka klasa Farmer nie byłaby równie dobra?

class Farmer
    {
        public int BagsOfFeed { get; private set; }

        private int feedMultiplier;
        public int FeedMultiplier { get { return feedMultiplier; } set { feedMultiplier = value; } }

        public Farmer(int numberOfCows, int feedMultiplier)
        {
            FeedMultiplier = feedMultiplier;
            NumberOfCows = numberOfCows;
        }

        private int numberOfCows;
        public int NumberOfCows
        {
            get
            {
                return numberOfCows;
            }
            set
            {
                numberOfCows = value;
                BagsOfFeed = numberOfCows * FeedMultiplier;
            }
        }
    }

Oba kody działają (przynajmniej tak mi się zdaje) identycznie.

Nurtuje mnie jeszcze jedna rzecz, we wcześniejszej wersji ćwiczenia nie było konstruktora. Gdy zamieniam linijkę utworzenia obiektu Farmer na taką:
farmer = new Farmer() { NumberOfCows = 15, FeedMultiplier = 30 };
To pole numberOfCows przyjmuje wartość 15, ale feedMultiplier ma wartość 0 zamiast 30.

0

Popatrz na konstruktor klasy. parametr numberOfCows zostaje wpisany do właściwości, która posiada akcesor get i set. Właściwość FeedMulipler nie posiada akcesora set. Nie można jej przypisać wartości można tylko pobrać, w związku z tym parametr z konstruktora zostaje przypisany do pola private feedMultipler, która to jest odczytywana przez właściwość FeedMultipler.

public Farmer(int numberOfCows, int feedMultiplier)
        {
            this.feedMultiplier = feedMultiplier;
            NumberOfCows = numberOfCows;
        }

 
0

mariano901229 - to rozumiem, ale chodziło mi o to, żeby obie te wartości były zadeklarowane za akcesora set. Już rozwiązałem problem:

Farmer:

class Farmer
    {
        public int BagsOfFeed { get; private set; }

        private int feedMultiplier;
        public int FeedMultiplier { get { return feedMultiplier; } set { feedMultiplier = value; } }

        private int numberOfCows;
        public int NumberOfCows
        {
            get
            {
                return numberOfCows;
            }
            set
            {
                numberOfCows = value;
                BagsOfFeed = numberOfCows * feedMultiplier;
            }
        }
    }

Form1:

Farmer farmer;
        public Form1()
        {
            InitializeComponent();
            farmer = new Farmer() { FeedMultiplier = 30, NumberOfCows = 15 };
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Console.WriteLine("Potrzebuję {0} worków paszy do wykarmienia {1} krów", farmer.BagsOfFeed, farmer.NumberOfCows);
        }

        private void CowAmount_ValueChanged(object sender, EventArgs e)
        {
            farmer.NumberOfCows = (int)CowAmount.Value;
        }

Gdy kod tworzenia obiektu wyglądał tak: farmer = new Farmer() { NumberOfCows = 15, FeedMultiplier = 30 }; to najpierw program ustawiał zmienną numberOfCows i przypisywał wartość do BagsOfFeed a dopiero potem nadawał wartość FeedMultiplier. Dlatego program działał dopiero, gdy zmieniłem w nim ilość krów, dzięki czemu BagsOfFeed został wyliczony z odpowiednim FeedMultiplier.

0
Ardoos napisał(a):

Zastanawia mnie dlaczego inaczej ustawiana jest wartość numberOfCows a inaczej foodMultiplier skoro obie wartości są inicjowane przez konstruktur?
.

Po mojemu to w celach edukacyjnych, żeby przypomnieć o słowie kluczowym this.

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