2008-11-03 18 views
9

Po prostu interesują mnie opinie ludzi. Podczas korzystania zerowalne typów w C# Jaka jest praktyka sposób najlepiej przetestować dla wartości null:Używanie typów zerowalnych w języku C#

bool isNull = (i == null); 

lub

bool isNull = !i.HasValue; 

Również podczas przypisywania do niepuste typu to:

long? i = 1; 
long j = (long)i; 

lepiej niż:

long? i = 1; 
long j = i.Value; 

Odpowiedz

12

Skorzystaj z formularzy, które zostały specjalnie zaimplementowane przez zespół C#. Jeśli ktokolwiek się sprzeciwi, powiedz, że Anders powiedział, że to w porządku.

To, co mówię, nieprzyzwoicie, polega na tym, że wiele pracy polegało na integracji typów zerowych w języku C#, aby zapewnić dobre wrażenia z programowania.

Należy zauważyć, że pod względem wydajności, obie formy skompilować dół do samej IL, czyli:

int? i = 1; 
bool isINull = i == null; 
int j = (int)i; 

kończy się tak po kompilator C# ma do niego:

int? i = 1; 
bool isINull = !i.HasValue; 
int j = i.Value; 
8

I wo zawsze używaj formularza (i == null). Wyraża to, co robisz.

WRT drugie pytanie, myślę, że albo forma jest w porządku. Jednak zawsze sprawdzałem najpierw wartość zerową i podejmowałem odpowiednie działanie - być może zawijanie tego czeku i działania w górę w metodzie pomocnika (często po prostu ustawia wartość domyślną).

0

Oba są takie same, ale używałbym poprzedniej wersji na obu, ponieważ jest bardziej powszechna w tym języku: porównanie z wartością zerową i rzutowanie na typ.

0

zwykle mają tendencję do skłaniają się ku pierwszej opcji w obu scenariuszach, ponieważ jest to bardziej „prymitywne” zorientowane przeciwieństwie do obiektowego (co było naprawdę co my jechaliśmy za), ale to naprawdę nie ma znaczenia, że ​​wiele

14

użyłbym to:

long? i = 1; 
...some code... 
long j = i ?? 0; 

oznacza to, że jeśli i jest zerowy, niż 0 zostanie przypisany.

+1

również, jeśli chcesz przypisać wartość domyślną dla tego typu wartości (który może być 0), możesz użyć długiego j = i ?? default (długi); –

+0

Problem, który mam z trhat formy jest to, że nie wszyscy deweloperzy będą wiedzieć, co się dzieje od razu. –

+0

Bardzo fajnie - nie odkryłem? operator lub "default" jeszcze. –

4

W praktyce nie stosowałem typów nullable, ale na drugi faktycznie zasugerowałem użycie j.GetValueOrDefault(). Dokumentacja sugeruje, że ta ostatnia faktycznie rzucił wyjątek InvalidOperationException w przypadku wartości pustej. W zależności od wewnętrznej implementacji operatora odrzucającego na długi czas, ten pierwszy też mógłby. Pozostanę przy GetValueOrDefault i odpowiednio potraktuję wartość pustą/domyślną.

1

I zwykle używają pierwszego z nich, ponieważ, ponieważ musi być wspierany w późniejszym cyklu życia, wydaje się, że łatwiej jest zrozumieć, jaki jest zamiar pierwotnego pisarza.

1

Otwarty reflektor. HasValue to wyszukiwanie flagi binarnej, która jest ustawiana po zmianie wartości. Więc jeśli chodzi o cykle, wyszukiwanie będzie szybsze niż porównywanie.

public Nullable(T value) 
{ 
    this.value = value; 
    this.hasValue = true; 
} 

private bool hasValue; 

internal T value; 

public bool HasValue 
{ 
    get 
    { 
     return this.hasValue; 
    } 
} 
+0

Czy sprawdziłeś porównanie porównania? Byłbym zaskoczony, gdyby syntaktyczny cukier zakończył się niczym innym niż wywołaniem HasValue. – mackenir

Powiązane problemy