Rozumiem różnice w zdolnościach i wartościach, które mogą reprezentować, ale wydaje się, że ludzie zawsze używają, Int32
niezależnie od tego, czy jest to właściwe. Wydaje się, że nikt nigdy nie używa wersji bez znaku ( uint
), mimo że przez większość czasu pasuje ona lepiej, ponieważ opisuje wartość, która nie może być ujemna (być może reprezentuje identyfikator rekordu bazy danych). Ponadto wydaje się, że nikt nigdy nie używa, short/Int16
niezależnie od wymaganej pojemności wartości.
Obiektywnie, istnieją przypadki, w których lepiej użytku uint
lub short/Int16
a jeśli tak, to jakie one są?
null
niż dodatni lub ujemny. Jeśli myślisz o tym jako o czymś, co nigdy nie może być negatywne lub zawsze jest pozytywne, będziesz zaskoczony (i często zły) na wyniki, ponieważ tak naprawdę nie działa w ten sposób, zwłaszcza w porównaniu z / odejmowanym do / z podpisanych wartości.Odpowiedzi:
Podejrzewam, że masz na myśli perspektywę pokolorowaną własnymi doświadczeniami, w której nie pracowałeś z ludźmi, którzy właściwie używają typów integralnych. Może to być częste zjawisko, ale z mojego doświadczenia wynika, że ludzie często używają ich poprawnie.
Korzyścią jest miejsce w pamięci i czas procesora, być może także przestrzeń we / wy, w zależności od tego, czy typy są kiedykolwiek przesyłane przewodowo, czy na dysk. Niepodpisane typy zapewniają sprawdzanie kompilatora, aby upewnić się, że nie wykonasz pewnych operacji, które są niemożliwe, a także rozszerzenie dostępnego zakresu przy jednoczesnym zachowaniu mniejszego rozmiaru w celu zwiększenia wydajności tam, gdzie może to być konieczne.
Prawidłowe stosowanie jest jak można się spodziewać - zawsze wiesz na pewno, można z nich korzystać na stałe (nie ograniczają bez pewności czy ty będziesz żałować później).
public uint NumberOfPeople
), użyj typu bez znaku.public byte DamagedToothCount
), użyj bajtu.public short JimmyHoffasBankBalance
).public int HoursSinceUnixEpoch
).public long MyReallyGreatAppsUserCountThisIsNotWishfulThinkingAtAll
).Takie rozumowanie można wykorzystać do wyboru między podpisanymi, niepodpisanymi i różnymi rozmiarami typów itp. Pomyśl tylko o logicznych prawdach danych, które reprezentujesz w rzeczywistości.
źródło
int
wszędzie, chyba że wiesz, że domena problemowa faktycznie ogranicza wartość - żaden bank nie chciałby ograniczyć rachunków do 33 tys. Funtów (i pomyśleć o dobrej zabawie kiedy to się przelewa…!).long
. Oszczędność pamięci może oczywiście pośrednio zaoszczędzić czas poprzez poprawę wydajności linii pamięci podręcznej i tak dalej, ale OTOH problemy z wyrównaniem małych typów mogą pośrednio kosztować czas.Jasne, są przypadki, w których lepiej jest użyć
uint
lubshort
lubInt16
. Jeśli wiesz, że twój zakres danych będzie pasował do ograniczeń tego typu zmiennej, możesz użyć tego typu.W środowiskach o ograniczonej pamięci lub w przypadku dużych ilości obiektów sensowne może być użycie najmniejszej zmiennej wielkości. Na przykład, istnieje znacząca różnica wielkości dla tablicy milionów elementów
int
s w porównaniu zshort
s.Często nie dzieje się tak w rzeczywistym kodzie z jednego lub więcej z następujących powodów:
Jest o wiele więcej możliwych przyczyn, ale sprowadzają się one do tego: czas poświęcony na podjęcie decyzji i użycie innego typu zmiennej nie zapewnił wystarczającej korzyści, aby to uzasadnić.
źródło
W C, w kontekstach nieobjętych promocją liczb całkowitych , określono niepodpisane wartości, które będą zachowywać się jak elementy „zawijającego” abstrakcyjnego pierścienia algebraicznego (więc dla każdego X i Y, XY da unikalną wartość, która po dodaniu do Y da X ), podczas gdy typy liczb całkowitych ze znakiem były określone jako zachowujące się jak liczby całkowite, gdy obliczenia pozostawały w określonym zakresie, i pozwalały na wykonanie dowolnej czynności, gdy obliczenia wykraczały poza to. Jednak semantyka numeryczna w języku C # jest zupełnie inna. W sprawdzonym kontekście liczbowym zarówno podpisane, jak i niepodpisane typy zachowują się jak liczby całkowite, pod warunkiem, że obliczenia pozostają w zasięgu i rzucają,
OverflowException
gdy nie; w niesprawdzonym kontekście oba zachowują się jak pierścienie algebraiczne.Jedynym czasem, w którym ogólnie warto jest użyć dowolnego typu danych mniejszego niż
Int32
jest to konieczne, gdy konieczne jest pakowanie lub rozpakowywanie rzeczy w celu kompaktowego przechowywania lub transportu. Jeśli trzeba zapisać pół miliarda liczb dodatnich, a wszystkie będą w zakresie od 0 do 100, użycie jednego bajtu zamiast czterech spowoduje oszczędność 1,5 gigabajta pamięci. To duże oszczędności. Jeśli jednak fragment kodu musi przechowywać w sumie kilkaset wartości, uczynienie każdego z nich jednym bajtem zamiast czterech pozwoliłoby zaoszczędzić około 600 bajtów. Prawdopodobnie nie warto się tym przejmować.Jeśli chodzi o typy niepodpisane, naprawdę przydatne są tylko podczas wymiany informacji lub dzielenia liczb na części. Jeśli na przykład trzeba wykonać matematykę na 96-bitowych liczbach całkowitych, prawdopodobnie łatwiej będzie wykonać obliczenia na grupach trzech 32-bitowych liczb całkowitych bez znaku, niż na grupach liczb całkowitych ze znakiem. W przeciwnym razie nie ma zbyt wielu sytuacji, w których zakres podpisanej 32- lub 64-bitowej wartości byłby nieodpowiedni, ale wystarczający byłby ten sam rozmiar niepodpisanej wartości.
źródło
Generalnie złym pomysłem jest używanie typów niepodpisanych, ponieważ przepełniają się w nieprzyjemny sposób.
x = 5-6
jest nagle w twoim kodzie czasową bombą zegarową. Tymczasem korzyści z niepodpisanych typów sprowadzają się do jednego dodatkowego kawałka precyzji, a jeśli ten kawałek jest dla ciebie tego wart, prawie na pewno powinieneś użyć większego typu.Są przypadki użycia, w których mniejszy typ może mieć sens, ale chyba że martwisz się zużyciem pamięci lub koniecznością spakowania danych w celu zwiększenia wydajności transmisji lub pamięci podręcznej lub kilku innych problemów, zazwyczaj nie ma korzyści z używania mniejszego typu . Co więcej, na wielu architekturach korzystanie z tych typów jest wolniejsze, więc mogą one nałożyć niewielki koszt.
źródło
i+1>i
pod1
jeślii
jest podpisana, wraz z niezliczoną liczbą innych paskudne zachowanie. Niepodpisane przepełnienie może spowodować błąd w skrzynce narożnej. Podpisany przepełnienie może sprawić, że cały program będzie bez znaczenia .Często zapomnianym i prawdopodobnie stycznym do twojego pytania, szczególnie w przypadku typów .NET, jest Zgodność z CLS . Nie wszystkie typy są dostępne dla wszystkich języków zbudowanych w .NET Framework.
Jeśli piszesz kod, który ma być używany przez języki inne niż C #, i chcesz, aby kod ten współpracował z jak największą liczbą języków .NET, musisz ograniczyć użycie tego typu do tych, które są zgodne z CLS.
Na przykład wczesne wersje VB.NET (7.0 i 7.1) nie obsługiwały liczb całkowitych bez znaku (
UInteger
):Niezapisane liczby całkowite nie są zgodne z CLS, dlatego należy zachować ostrożność, jeśli nie masz pewności, kto będzie Twoim konsumentem biblioteki klas.
źródło