2010-01-28 21 views
12

Chciałbym mieć zmienną całkowitą, która może mieć wartość NULL i nie chce używać składni int? myVariable. Próbowałem używać int i Int16 bezskutecznie. Czy muszę używać int? myVariable?Co to jest typ odniesienia integer w C#?

Wspominałem o tym, ponieważ w Javie jest zarówno typ "int" (prymitywny) i "Integer" (typ odniesienia). Chciałem mieć pewność, że nie ma wbudowanego typu odniesienia, którego mógłbym użyć. Będę używał "int?" za to, co robię.

+5

... Dlaczego nie chcesz użyć tej składni? – womp

+3

@Jon, To jest jak ... Chcę, żeby kompilator wiedział to beze mnie. – Dykam

Odpowiedz

26

Dla informacji, int?/Nullable<T> jest nie typu referencyjnego; jest to po prostu "typ zerowalny", oznaczający: znacznik struct (zasadniczo i int i bool) ze specjalnymi regułami kompilatora (kontrole re null, operatory, itp.) i regułami CLI (dla boksowania/rozpakowywania). Nie jest nie „odniesienia typu liczba całkowita” w .NET, jeśli nie liczyć boks:

int i = 123; 
object o = i; // box 

ale to stwarza niepotrzebną obiektu i ma wiele innych związanych z nimi problemów.

Dla tego, co chcesz, int? powinno być idealne. Możesz może używać używać składni długiej (Nullable<int>), ale IMO jest niepotrzebnie verbose, i widziałem to mylić ludzi.

+4

IMHO _? _ Zamieszanie zależy od tła - to mylić ruby ​​ludzi. Używamy Nullable to googlable i msdnable :) dla nowoprzybyłych –

+0

Jak poradzisz sobie ze scenariuszem, w którym masz IDictionary , który powiedzmy, że używasz jako liczby dla różnych obiektów. Kod "theDictionary [someObject] = newValue" nie działałby, ponieważ zwrócona wartość z wywołania indeksu ("[..]" nie jest odwołaniem do obiektu do tej samej wartości przechowywanej w instancji KeyValuePair słownika. Aby zwiększyć licznik, musisz usunąć KVP i dodać go ponownie, aby wpisać dowolne nowe wartości do KVP? Czy jest jakiś inny sposób? – Marchy

+1

@Marchy 'theDictionary [someObject] = newVal' będzie działać poprawnie; to jest przypisanie do indeksatora, który jest dobrze zdefiniowany i w pełni obsługiwany –

2

Tak, to jedyny sposób, ponieważ Int32/Int16/int jest typem pierwotnym (niezależnie od tego, czy jest to box/unboxing).

8

Tak należy użyć zerowalne typów

Zobacz Nullable

Nullable<int> Nullable<float> 

lub po prostu

int? float? 

PS:

Jeśli nie chcesz używać ? notacja lub Nullable w ogóle - po prostu używaj specjalnych struktur dla takich rzeczy. Na przykład DataTable:

var table = new DataTable(); 
table.Columns.Add('intCol',typeof(int)); 
var row = table.NewRow(); 
row['intCol'] = null; // 
+0

Należy zauważyć, że nie jest to typ odniesienia, jak w linku ("Reprezentuje typ wartości, które można przypisać null"). Ale odpowiada na podstawowy problem PO, jeśli nie na pytanie w tytule. – Kat

0

Składnia <var>? sprawia, że ​​pustych. Jeśli zagłębisz się nieco głębiej, zobaczysz, że jest to zwykły obiekt, który zostanie użyty.

Jeśli chcesz zrobić to jak C++, musisz użyć niebezpiecznych operacji. Następnie wskaźniki takie jak w C są dostępne, ale kod nie jest zgodny z CLR ...

Do korzystania z czystego .NET bez wskaźników, ? jest drogą do zrobienia.

+5

To nie jest obiekt, Nullable to struktura. –

0

Tak. Właśnie dlatego Microsoft to dodał. Ludzie tworzyli własną klasę Nullable, więc uwzględnili ten wzorzec w .NET.

0

Możesz użyć System.Nullable<int>, jeśli tak bardzo nienawidzisz ?.

0

Będziesz musiał użyć typu zerowalne, tj:

Nullable<int> or int? 

Celem wartości pustych typu jest, aby umożliwić przypisać wartość zerową do typu wartości.

Od MSDN:

typy dopuszczające wartość null adres scenariusza, w którym chcesz, aby móc mieć prymitywny typ z zerową (lub nieznane) wartości. Jest to powszechne w scenariuszach bazy danych, ale jest również przydatne w innych sytuacjach.

W przeszłości było kilka sposobów, aby to zrobić:

  1. typ wartości pudełkowej. Nie jest to silnie wpisane podczas kompilacji i wymaga alokacji sterty dla każdego typu.
  2. Owijacz klasy dla typu wartości. Jest to silnie wpisane, ale nadal wymaga alokacji sterty, a ty musisz napisać opakowanie.
  3. Strukturalne opakowanie obsługujące koncepcję zerowania. To dobre rozwiązanie, ale musisz sam to napisać.