Czy istnieje prosty atrybut lub kontrakt danych, który mogę przypisać do parametru funkcji, który zapobiega null
przekazywaniu w C # / .NET? Idealnie byłoby również sprawdzić w czasie kompilacji, aby upewnić się, że literał null
nie jest nigdzie używany do tego celu oraz w rzutach w czasie wykonywania ArgumentNullException
.
Obecnie piszę coś takiego ...
if (null == arg)
throw new ArgumentNullException("arg");
... za każdy argument, którego nie spodziewam się null
.
Z tej samej uwagi, czy istnieje odwrotność do sytuacji, w Nullable<>
której poniższe zawiodłyby:
NonNullable<string> s = null; // throw some kind of exception
c#
.net
parameters
null
Neil C. Obremski
źródło
źródło
Odpowiedzi:
Niestety w czasie kompilacji nic nie jest dostępne.
Mam trochę hakerskie rozwiązanie, które niedawno opublikowałem na swoim blogu, które wykorzystuje nową strukturę i konwersje.
W .NET 4.0 z zawartością Code Contracts życie będzie o wiele przyjemniejsze. Byłoby nadal całkiem fajnie mieć rzeczywistą składnię języka i obsługę braku wartości null, ale kontrakty kodu bardzo pomogą.
Mam również metodę rozszerzenia w MiscUtil o nazwie ThrowIfNull, która sprawia, że jest to nieco prostsze.
Ostatnia kwestia - jakikolwiek powód, dla którego warto użyć
if (null == arg)
” zamiast „if (arg == null)
”? Uważam, że ten drugi jest łatwiejszy do odczytania, a problem, który rozwiązuje ten pierwszy w C, nie dotyczy C #.źródło
if (null == x)
są naturalne różnice językowe. Uważam, że tak naprawdę chodzi o przestarzały styl, który propaguje się tylko poprzez przykłady itp.Wiem, że jestem niesamowicie spóźniony z tym pytaniem, ale czuję, że odpowiedź nabierze znaczenia, gdy ostatnia główna iteracja języka C # będzie bliżej wydania, a następnie wydania. W C # 8.0 nastąpi poważna zmiana, C # założy, że wszystkie typy nie są null.
Według Madsa Torgersena:
Tak więc rezolucja nakreślona przez Madsa to:
Przykład pożądanej funkcji:
Wersja zapoznawcza jest dostępna dla programu Visual Studio 2017, 15.5.4+ w wersji zapoznawczej.
źródło
Wiem, że to BARDZO stare pytanie, ale tego tutaj brakowało:
Jeśli używasz ReSharper / Rider, możesz użyć Annotated Framework .
Edycja : właśnie otrzymałem losową -1 dla tej odpowiedzi. W porządku. Po prostu pamiętaj, że jest on nadal aktualny, mimo że nie jest już zalecanym podejściem do projektów C # 8.0 + (aby zrozumieć, dlaczego, zobacz odpowiedź Grega ).
źródło
Sprawdź walidatory w bibliotece korporacyjnej. Możesz zrobić coś takiego:
Następnie w swoim kodzie, jeśli chcesz go zweryfikować:
źródło
nie najładniejsze ale:
możesz być bardziej kreatywny w metodzie ContainsNullParameters:
oczywiście możesz użyć przechwytywacza lub odbicia, ale są one łatwe do śledzenia / używania z niewielkim narzutem
źródło
return (from o in methodParams where o == null).Count() > 0;
Użyj:return methodParams.Any(o=>o==null);
będzie znacznie szybciej przy dużych kolekcjachOk, ta odpowiedź jest trochę spóźniona, ale oto jak ją rozwiązuję:
Użyj tej metody rozszerzenia, a następnie możesz traktować pusty i pusty ciąg jako to samo.
Na przykład
Wiem, że nie jest to idealne rozwiązanie, ponieważ musisz pamiętać, aby wywoływać domyślne wszędzie, ale jest to jedno rozwiązanie.
źródło
string.IsNotNullOrEmpty
naprawdę inne niż cukier wynikający z posiadania tego, na czym ci zależy, po lewej stronie. Może być wprowadzany do innych funkcji (długość, konkatenacja) itp. Nieznacznie lepiej.Default()
) na null (model.Day
). Wiem, że metody rozszerzeń nie są sprawdzane pod kątem wartości null, ale moje oczy nie są tego świadome i już sobie wyobrazili?
w kodzie:model?.Day?.Default()
:)