Wiem, że tytuł pytania jest bardzo subiektywny, ale spotkałem się z użyciem ??
operatora przez moich rówieśników, gdzie jednocześnie nie byłem bardzo zadowolony / komfortowo z zastosowania var
nowego kodu.
Argumentem podanym za pomocą ??
operatora było usunięcie czytelności kodu.
Moje pytanie brzmi: czy to samo nie dzieje się, kiedy zaczynasz używać var
?
c#
coding-style
readability
Numan
źródło
źródło
??
zerowego operatora koalescencji po jego wyjaśnieniu, nie powinien być dozwolony w pobliżu kodu produkcyjnego.Odpowiedzi:
Zerowy operator koalescencyjny (??)
Osobiście nie widzę żadnych wad korzystania z tego operatora. Rozważ następujące trzy przykłady kodu, od „łatwych” do „złożonych” nowych operatorów.
Bez magii:
Operator trójskładnikowy:
Brak koalescencji:
Powodem, dla którego wymyślono te operatory, jest to, że reprezentują one bardzo popularne operacje programistyczne . Nie chcę ich używać, ponieważ nie jesteś do nich przyzwyczajony, to tylko upór . Języki ewoluują, funkcje ewoluują, naucz się ich używać!
słowo kluczowe var
Mam nieco inne zdanie na temat słowa kluczowego var. Typ zmiennej często zapewnia dodatkowe informacje o kodzie. Uważam, że ukrywanie typu za pomocą słowa kluczowego var czasami sprawia, że kod jest mniej czytelny. Wiesz mniej, czego się spodziewać, bez korzystania z automatycznego uzupełniania lub najechania kursorem na identyfikatory, aby zobaczyć, jakie są w rzeczywistości. Moim zdaniem powoduje to, że kod jest wolniejszy do odczytu / zapisu.
Używam tego słowa kluczowego, gdy okazuje się, że ten typ nie zawiera wielu dodatkowych informacji.
Jako przykład ostatniej instrukcji:
źródło
Factory.CreateSomeType
zwracaIEnumerable<SomeType>
. Pewnego dnia, z jakiegokolwiek powodu, zmienia się w powrótSomeType[]
. Jeśli używałeś var, to tylko rekompilacja.Factory.CreateSomeType()
zmiany zwrócąISomeType
?null
całkowicie uniknąć . Co więcej, im więcej szukam alternatywnull
, tym bardziej zdaję sobie sprawę, że używanienull
jest czasem najczystszym rozwiązaniem. Mój podany przykład nie jest wcale taki zły IMHO, i uważam, że jest to właściwe użycie typów zerowalnych.var pozwala na mniej szczegółowy kod, co zwiększa czytelność. Moim zdaniem czytelność nie powinna być mierzona przez to, ile szczegółów widzisz, ale ile szczegółów jest ukrytych na pierwszy rzut oka. Oprócz przykładów Linq, var umożliwia pisanie kaczek na poziomie kodu źródłowego, biorąc pod uwagę następujący przykład:
Kogo to obchodzi, jaki jest rodzaj etykiety, o ile zapewnia ona właściwość Text?
źródło
Nie mam żadnych poważnych komentarzy na temat
??
operatora, ponieważ nigdy nie używałem języka z takim operatorem. Jeśli chodzi o tovar
, ludzie programują w językach takich jak Ruby, Python, Perl i PHP, które mają w pełni niejawne pisanie przez cały czas. Mieszkańcy tych języków zdają sobie sprawę, że formalnym typem zmiennej jest zwykle nieistotny hałas. Bardziej interesuje Cię to, co może zrobić zmienna , tj. Jej interfejs strukturalny / kaczka.Podobnie, programuję głównie w języku D. D jest wpisany statycznie, ale ma
auto
słowo kluczowe, które jest równoważnevar
. Używanie go wszędzie jest uważane za idiomatyczne, chyba że zauważysz konkretną potrzebę podkreślenia rodzaju czegoś czytnikowi lub (poprzez niejawną konwersję) kompilatorowi. Z wyjątkiem sytuacji, gdy używany jest jako typ zwracanej funkcji (jest to dozwolone w D), nigdy nie uważałem, że utrudnia to czytelność, ponieważ myślę głównie w kategoriach interfejsów strukturalnych / kaczych, a nie typów formalnych / nominalnych, kiedy programuję.Co więcej, używanie IMHO
var
wszędzie, gdzie jest to możliwe, jest dobrym przykładem SUCHEGO. Rodzaj czegoś powinien być określony w jednym i tylko jednym miejscu, a następnie automatycznie propagowany za każdym razem, gdy trzeba go propagować. Jeśli użyjesz,var
a formalny typ zmiennej musi się w pewnym momencie zmienić, niezbędne zmiany zostaną automatycznie rozpowszechnione wszędzie tam, gdzie jest to konieczne, o ile program jest nadal poprawny pod względem typu, a nie programista musi ręcznie zmieniać każdą instancję . To jest Dobra Rzecz (TM).źródło
Myślę, że to ostatecznie pytanie do zespołu. Jeśli nie jest to czytelne dla nikogo w moim zespole, nie będę go używał, chociaż mógłbym spróbować kilka razy, aby przekonać ich przykładami lub wskazując podobne skróty (takie jak + =), które uważają za bardziej czytelne.
Jeśli jednak pracuję sam, to znajdę? i var doskonale czytelne bez ograniczeń. Parzysty
jest dla mnie dość jednoznaczny.
Operatory trójskładnikowe i
dynamic
to oczywiście inna sprawa.źródło
var a = b ?? c ?? d ?? e ?? String.Empty ?? "";
String.Empty
kiedykolwiek powrócinull
, czeka nas cholernie dużo zepsutego kodu.Krótko o tym myśląc, ten komentarz mówi mi, że osoba, która go komentuje, nie rozumie go tak dobrze, jak powinna. Jest to najprawdopodobniej prawda w niektórych sytuacjach, ale ogólnie rzecz biorąc, nie pomijam czegoś, co zespół C # najwyraźniej uważał za wystarczająco ważne, aby dodać ze względu na „czytelność”. Ja to w tej samej kategorii
if(boolean_object)
vsif(boolean_object == true)
. Niektórzy twierdzą, że drugi jest bardziej czytelny, ale w rzeczywistości jest to po prostu dodanie dodatkowego kodu do czytania / pisania, a w niektórych sytuacjach może być bardziej mylące (pomyślif(boolean_object != false)
)Zespół C # pozwolił ci nie definiować czegoś, co wiesz, co to będzie. O ile nie muszę absolutnie określać, jaka będzie zmienna (albo absolutnie ważne jest, aby zwracany obiekt był typu x, albo naprawdę nie jest czytelny), używam
var
.var x = "MY_STRING";
Wiem, że to ciąg od patrzenia na to. Prawdę mówiąc, tak naprawdę nie dbam o to, że to sznurek, o ile robi to, czego potrzebuję. Zdefiniowanie typu zmiennej jest dla mojej korzyści, a nie kompilatora. Jeśli coś jest nie tak, kompilator powie mi, kiedy działa, jeśli mam zły typ zmiennej.źródło
var
Kluczowe jest, moim zdaniem, pokonał stosowane w sytuacjach, dla których to było oryginalne wprowadzono - zapytań LINQ. W tych zapytaniach typ zwracanego wyniku często ma dużą, skomplikowaną nazwę, która jest trudna do ustalenia z góry i nie pomaga czytelnikowi zrozumieć, co robi Twój kod.Jednak robienie tego
var text = "Some text " + variableName + "some more text."
jest po prostu leniwe.EDYCJA: @Jorg Skoczyłeś na celowo uproszczoną odpowiedź, ale nic nie dodałeś do dyskusji. OK, co powiesz na lepszy przykład:
var items = doc.DocumentElement.FirstChild.ChildNodes;
jeśli możesz dowiedzieć się, na podstawie tego typu, dam ci ciasteczko.źródło
"Some text "
jest tostring
a, masz o wiele większe problemy do zmartwienia niż liczbavar
s w kodzie.var
; problemem jest kiepska nazwa zmiennej „items”. Jeśli użyjesz dobrej nazwy zmiennej, nie ma w tym nic złegovar
.Mam podstawowy problem z używaniem var.
W tym przykładzie wszystko działa obok siebie, ale problem dotyczy naprawdę dużych rozwiązań ze współdzielonymi bibliotekami lub projektami.
Rozważ to:
Co się stanie, jeśli GetMeAnObject zostanie zmieniony przez kogoś innego, w zależności od jego potrzeb?
Metoda MainProgram będzie miała duży czerwony błąd na .PerformOperation (). Co się stało? PerformOperation działał wcześniej doskonale. Patrzymy na metody w obiekcie i po prostu zniknął bez śladu. Był tam ostatni raz i potrzebujemy tej metody. Mógłbyś spędzać dużo czasu na ściganiu ogona i próbowaniu dowiedzieć się, dlaczego, jeśli MyFirstObject ma metodę o nazwie PerformOperation, nie można jej teraz zobaczyć. Każdy „wie”, że GetMeAnObject zwraca MyFirstObject, więc nie ma sensu tego sprawdzać.
Jeśli wpisałeś jawnie obiekt, wówczas wystąpiłby błąd nieprawidłowego rzutowania w linii, która wywołuje GetMeAnObject, i byłoby oczywiste, że GetMeAnObject zwraca typ, który nie jest tym, czego oczekujesz.
Krótko mówiąc, wyraźne oświadczenie oznacza, że wiesz, co oznaczają błędy. Nieprawidłowa obsada oznacza, że oczekiwano jednego typu, a inny typ został zwrócony. Nierozpoznany członek oznacza, że członek został nierozpoznany.
źródło
var
? Nie można oczekiwać, że język ochroni się przed tego rodzaju zachowaniami - co jeśli bezpośrednio zmodyfikują MyFirstObject? Nadal by się zepsuł, ale żadna składnia nie mogłaby cię przed tym uratować.var
Uznałbym to za siłę nawet: co, jeśli zamiast zwracać MySecondObject, zwracasz teraz IMyFirstObject?