• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

C# konstruktor

0 głosów
112 wizyt
pytanie zadane 1 października 2020 w C# przez Comparion Obywatel (1,800 p.)
public class MeetupSeeder
    {
        private readonly MeetupContext _meetupContext;

        public MeetupSeeder(MeetupContext meetupContext)
        {
            _meetupContext = meetupContext;
        }
    }

 

 

czy kotś mógłby mi wyjaśnić po co się robi taki kostruktor z polem tylko do odczytu z innej klasy? Bardzo często ostatnio spotykam taki zapis, nie do kona rozumiem po co się tak robi. Chodzi mi o ogólne założenie, nie akurat w tym przypadku.

2 odpowiedzi

+1 głos
odpowiedź 1 października 2020 przez marcin99b Maniak (71,530 p.)

Poczytaj o dependency injection

Ogólnie chodzi o to, że wszelkie zależności lepiej mieć konfigurowalne z zewnątrz niż wewnątrz
Bo przy większej skali projektu można dużo prościej coś zmienić

Możesz dodatkowo poczytać o IoC i kontenerach IoC -> w których rejestrujesz jak konkretne obiekty mają być tworzone
po czym prosisz o instancje konkretnego obiektu jak go potrzebujesz

Przez to masz taki punkt sterowania/zarządzania tworzeniem obiektów
(prościej sie zarządza mając jeden większy punkt zarządzania, niż mając wszystko rozbite na pojedyncze przypadki użycia)

No i też prościej sie tworzy obiekty
Wyobraź sobie że masz obiekt który ma 3-5 zależności
Z czego każda z nich ma po 3-5 zależności

W IoC wszystko będzie ładne i czytelne
A robiąc to ręcznie, w dodatku w każdym przypadku osobno
Stracisz mase czasu i nerwów, a w dodatku będziesz miał nadmiarowy kod

+1 głos
odpowiedź 4 października 2020 przez sunzi Bywalec (2,000 p.)
edycja 4 października 2020 przez sunzi

po co się robi taki kostruktor z polem tylko do odczytu z innej klasy

Generalnie idea modyfikatora readonly jest dość prosta. Chodzi o dwie kwestie (ale być może są jeszcze inne zalety które przez nieuwagę pominąłem):

  • Łatwiej taki kod się czyta. Co to znaczy? Chodzi o to, że widząc deklaracje private readonly Foo bar; wiesz i masz gwarancję[1], że te pole nie zostanie nadpisane nigdzie poza konstruktorem. To znaczy, że gdzieś w środku kodu e innej metodzie nie będzie przypisania typu np. bar = new Foo(); i to masz zagwarantowane poprzez kompilator - inaczej taki kod się nie skompiluje. Dokładnie takie samo zadanie daje private - też daje pewne gwarancje od strony kompilatora.
  • Można precyzyjniej wyrazić intencje użycia danego pola. Co mam na myśli przez słowo intencje? To stosunkowo proste. Np. int a; wyraża intencje, że ta zmienna będzie przechowywać liczby (int) a nie stringi lub inne obiekty; z drugiej strony object a; wyraża, że zmienna a może zawierać każdy obiekt i trudno jest stwierdzić jaki - trzeba przeczytać resztę kodu aby się dowiedzieć. Tak samo jak private wyraża, że ta zmienna nie powinna być widoczna bezpośrednio na zewnątrz danej klasy. Tak samo readonly mówi "te pole nie będzie nadpisane w żadnej metodzie tej klasy - przypisanie pola będzie możliwe tylko i wyłącznie w konstruktorze (lub podczas konstrukcji obiektu)"
  • być może (podkreślam, być może) daje to większe szanse kompilatorowi na optymalizację (w końcu kompilator dostaje więcej informacji na temat użycia danego pola). Osobiście w to śmiem wątpić - ale może kompilator robi z tego jakiś użytek - ale to kwestia do sprawdzenia.

Dwa powyższe punkty nieco się przenikają ale taki jest ogólny sens tego modyfikatora.

Gdy pole nie ma modyfikatora readonly to nie ma tego komfortu podczas czytania (czy nawet pisania!) kodu - aby dowiedzieć się, czy pole te jest nadpisywane, musisz prześledzić wszystkie użycia danego pola manualnie (nie zrobi tego za Ciebie kompilator). W przeciwnym wypadku (jeśli nie prześledzisz użyć) nie możesz być pewny, że to pole nie jest nadpisywane gdziekolwiek indziej w obrębie danej klasy.

W wielu przypadkach ma to niebagatelne znaczenie w przypadku debuggowania/refactoringu czy po prostu próby zrozumienia danego kodu - po prostu lepiej i szybciej można zrozumieć w jaki sposób dane pole jest używane. Nie zawsze jest to kluczowe, ale bardzo często ułatwia to pracę.

Generalnie warto dodawać ten modyfikator jeśli z założenia pewnych pól nie będziemy chcieli nadpisywać. Ułatwia to czytanie i utrzymanie takiego kodziku.

[1] W sumie to gwarancji nigdy nie ma, bo jest refleksja, ale w typowym kodzie refleksja powinna być wykorzystywana ekstremalnie rzadko. Pisanie o gwarancji jest lekko naciągane, ale skupiłem się na typowym użyciu a nie wyjątkach od reguły.

Podobne pytania

–1 głos
1 odpowiedź 121 wizyt
pytanie zadane 6 października 2018 w C# przez konu33 Nowicjusz (210 p.)
0 głosów
1 odpowiedź 137 wizyt
pytanie zadane 19 listopada 2020 w C# przez Muzykowy Nowicjusz (120 p.)
+1 głos
1 odpowiedź 296 wizyt
pytanie zadane 12 sierpnia 2019 w C# przez moringnewbie Nowicjusz (180 p.)

85,774 zapytań

134,555 odpowiedzi

298,695 komentarzy

56,666 pasjonatów

Advent of Code 2021

Top 15 użytkowników

  1. 64p. - nidomika
  2. 62p. - ScriptyChris
  3. 60p. - Whistleroosh
  4. 57p. - adrian17
  5. 55p. - B4mbus
  6. 55p. - CC PL
  7. 53p. - Klaudia
  8. 50p. - WhiskeyTaster
  9. 47p. - rucin93
  10. 45p. - tokox
  11. 44p. - Adrian Rębisz
  12. 43p. - Michał Tartanus
  13. 41p. - Jarosław Roszyk
  14. 38p. - Argeento
  15. 18p. - Marcin Harasimowicz
Szczegóły i pełne wyniki

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...