Nie rozumiem co daje ten zapis <Nullable>enable</Nullable> ?

0

Jest to mój pierwszy wpis na tym forum więc dziękuje za przyjęcie. Do tej pory jedynie czytałem wpisy innych ale jako, że stanąłem przed z jednej strony trywialnym problem ale z drugiej strony nastręczającym mi kłopot z jego zrozumieniem postanowiłem zadać pytanie.

Pytanie 1
Otóż przerabiając już dość dawno temu jakiś tutorial z .Net WebApi Core gdzie auto wytłumaczył, że dzięki tej opcji <Nullable>enable</Nullable> jesteśmy w stanie do zmiennych typu prostego przypisywać wartość "null" co jest dla mnie jasne i ani się nad tym nie zastanawiałem więcej, ani tego nie testowałem, aż do dziś. Trochę się pobawiłem i okazało się, niezależnie od tego czy mam tą opcję aktywną czy nie to do int-a jestem w stanie przypisać "null" tylko wtedy gdy użyje znaku zapytania "?". Więc co ta opcja tak naprawdę robi?

Pytanie 2
Po co oznacza się typy zmiennych znakiem zapytania (na przykład string? a)? Według informacji które znalazłem pozwala to na przypisanie do typu prostego wartości null co jest jasne. Czyli jeśli w DTO oznaczę właściwość typu np. int znakiem zapytania to jest ona w stanie przyjąć null, a tym samym staje się opcjonalna. Tylko po co wtedy oznaczać wartości typu string znakiem zapytania skoro one przyjmują null-a z klucza? Jeśli natomiast tego nie zrobię to okazuje się, że taki string bez znaku zapytania staje się wymagany. Jest to dla mnie nie logiczne ale może
jest tego jakieś sensowne wytłumaczenie, czy po prostu takie są zasady i już?

Pytanie 3
Do czego służy "default!"? Co daje wykrzyknik na końcu ? Po wstępnych próbach zarówno wersja z ! jak i bez przypisuje 0 do wartości prostych i null do wartości referencyjnych pod warunkiem że typ prosty oznaczem ?

1

Ja twierdzę, że Microsoft nie potrafi sobie poradzić z NullReferenceException i zrobił nullable żeby ci przypomnieć w kodzie żebyś robił ify na nulle 😂

1
AdamWox napisał(a):

Ja twierdzę, że Microsoft nie potrafi sobie poradzić z NullReferenceException i zrobił nullable żeby ci przypomnieć w kodzie żebyś robił ify na nulle 😂

Ty tak serio ?

Hi_i_By napisał(a):

Pytanie 2
Po co oznacza się typy zmiennych znakiem zapytania (na przykład string? a)? Według informacji które znalazłem pozwala to na przypisanie do typu prostego wartości null co jest jasne.
\

Jak widziałeś gdzieś string ? to było żle.
string jest sam w sobie nullable

C#, inaczej niz Java (choć to prawie kopia) ma nie dwupodział, a trójpodział.
referencje na typ class , w pelni moga być nullable (tak samo w Javie). string jest klasą.

zmienne proste, integer, boolean. Do integerea gołego w rygorystycznym języku nie można przypisać referencji, sprzeczność typów. To wyczytałeś

C#, czego nie ma w Javie, ma zmienne o typie struct , przeznaczonym dla względnie prostych konglomeratów danych (żaden z nich nie może byc class). Zmienna typu struct jest przechowywana na stosie (jak zmienne proste), nie jest zagospodarowana przez GC itd... ważnym przykładem jest struct DateTime
I te zmienne nie są nullable by default. Są w tym podobne (wybaczcie) do leżących na stosie zmiennych strukturalnych C.

napisz

DateTime something;
something = null;

dostaniesz błąd.

4
AnyKtokolwiek napisał(a):

Jak widziałeś gdzieś string ? to było żle.
string jest sam w sobie nullable

Źle w jakim sensie?
Bo jak masz ustawione <Nullable>enable</Nullable> to właśnie przy typach referencyjnych dopisujesz ? jeśli z jakiegoś powodu mogą przyjmować null.

0
some_ONE napisał(a):
AnyKtokolwiek napisał(a):

Jak widziałeś gdzieś string ? to było żle.
string jest sam w sobie nullable

Źle w jakim sensie?
Bo jak masz ustawione <Nullable>enable</Nullable> to właśnie przy typach referencyjnych dopisujesz ? jeśli z jakiegoś powodu mogą przyjmować null.

Trochę uchylam sie w wypowiedzi od środowisk klasy XML np ASPX, WPF i podobne, mówię o czystym C#

2

Ja też, od C# 8 jest ten feature.

2

Nie programuje w C#
ale rozumiem, że jak w projekcie masz ustawione <Nullable>enable</Nullable> to by default twoje referencje nie są nullable, logiczne.

Swoją drogą super użyteczny feature, miejsce null w kodzie "aplikacji końcowych/użytkowych" jest na śmietniku historii. (a java tego nadal nie ma).

5

To domyślna wartość w nowych projektach ale dla kompatybilności wstecznej powoduje tylko warningi.
Powinieneś dodać jeszcze:

<WarningsAsErrors>Nullable</WarningsAsErrors>

dzięki temu kod się nie skompiluje jeśli będziesz próbował przypisać nulla bez jawnego wyrażenia takiego zamiaru i jawnie nie pokażesz że zmienna może przyjąć null, np: string? lub nie zapewnisz kompilator że tego nulla tam nigdy nie będzie przez dodanie ! na końcu - to głównie przydatne do pracy ze starymi bibliotekami

0
obscurity napisał(a):

dzięki temu kod się nie skompiluje jeśli będziesz próbował przypisać nulla bez jawnego wyrażenia takiego zamiaru i jawnie nie pokażesz że zmienna może przyjąć null, np: string? lub nie zapewnisz kompilator że tego nulla tam nigdy nie będzie przez dodanie ! na końcu - to głównie przydatne do pracy ze starymi bibliotekami

Nasunęło mi się jeszcze jedno pytanie. Mianowicie po co stosować "default!" ? Zapis ten sprawi że do zmiennej typu referencyjnego zostanie przypisana wartość null co w połączeniu z ! jest sprzecznością. Czy dobrze to rozumiem, że jeśli użyję "default!" to jawnie poinformuje kompilator, że chwilowo do zmiennej ma zostać przypisana wartość null, ale po starcie programu już nigdy null tam się nie pojawi?

2

Nie powinieneś pisać default! czy null! bo tak jak mówisz wpisujemy wtedy nulla i mówimy że go tam nie ma. Takie default! jest głównie stosowane w przykładach na necie żeby uprościć przykład, W niektórych sytuacjach się też przydaje jak mamy coś w rodzaju "inicjatora" i stan obiektu się pojawia zaraz po konstruktorze, asynchronicznie lub np przez refleksję przez deserializację a słówko kluczowe required wymusza żebyśmy coś tam wstępnie przypisali i jesteśmy pewni że nie użyjemy obiektu przed tym jak jest w pełni gotowy.
Ale to proszenie się o problemy - ogólnie unikać jeśli się da. Najlepiej użyć "null object" w takim miejscu lub zamiast tworzyć niegotowy obiekt i go uzupełniać później zlecić asynchroniczne tworzenie obiektu klasie trzeciej.

1

Pisze "default!" do właściwości w modelach DTO oraz bazodanowych wówczas nie mam worningów ze strony kompilatora. Myślisz, że w takim kontekście moje podejście jest również błędne i powinienem zrezygnować z tego zapisu ?

1

Tak, jeśli możesz użyć C# 11 to dodaj słówko required zamiast tego. Do DTO możesz też użyć rekordów.

0
AnyKtokolwiek napisał(a):

Jak widziałeś gdzieś string ? to było żle.
string jest sam w sobie nullable

Oczywiście, że zapis string? jest jak najbardziej poprawny i szeroko stosowany przez Microsoft. Dla mnie nie ma on większego sensu (jak i dla Ciebie), jednak w dokumentacji jasno jest napisane, że nullable z typem referencyjnym jest po to, żeby dać znać programiście, że tutaj może być null. Innymi słowy:

string? GetSomeString() {}

może zwrócić null, a taki zapis:

string GetSomeString() {}

wg prawilnych dokumentacji MS, NIE POWINIEN zwrócić nulla, tylko ZAWSZE jakąś wartość.

Czy to sensowne? To chyba kwestia osobista. W przypadku string ja i tak zawsze używam string.IsNullOrWhitespace(str). W przypadku typów referencyjnych mój kod albo zwraca prawilny obiekt, albo nulla :)
Jedna z praktyk mówi, że nie powinno się zwracać nulli. Ja się z tym nie zgadzam i uważam, że zwracanie nulli w pewnych sytuacjach ma swój sens. Natomiast tutaj ten nullable chyba właśnie jest kwestią pewnego kompromisu.

Ja w swoich kodach raczej mam wyłączone nullable, bo mnie po prostu denerwuje. A potem stawiać jakieś wykrzykniki, czy coś (żeby pozbyć się warninga) też jest nieeleganckie.

2
Juhas napisał(a):

Jedna z praktyk mówi, że nie powinno się zwracać nulli. Ja się z tym nie zgadzam i uważam, że zwracanie nulli w pewnych sytuacjach ma swój sens. Natomiast tutaj ten nullable chyba właśnie jest kwestią pewnego kompromisu.

Ja w swoich kodach raczej mam wyłączone nullable, bo mnie po prostu denerwuje. A potem stawiać jakieś wykrzykniki, czy coś (żeby pozbyć się warninga) też jest nieeleganckie.

Skoro null ma sens w pewnych sytuacjach, to czemu zezwalasz na niego wszędzie, zamiast tylko w pewnych sytuacjach?

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