Ich verstehe die Unterschiede in der Kapazität und den Werten, die sie darstellen können, aber es scheint, als würden die Leute immer etwas verwenden, Int32
unabhängig davon, ob es angemessen ist. Niemand scheint jemals die vorzeichenlose Version ( uint
) zu verwenden, obwohl sie häufig besser passt, da sie einen Wert beschreibt, der nicht negativ sein kann (möglicherweise um eine ID eines Datenbankdatensatzes darzustellen). Auch scheint niemand jemals short/Int16
unabhängig von der erforderlichen Kapazität des Werts zu verwenden.
Objektiv gesehen, gibt es Fälle, in denen es besser ist, sie zu verwenden, uint
oder, short/Int16
wenn ja, welche?
null
als positiv oder negativ. Wenn Sie es als etwas betrachten, das niemals negativ oder immer positiv sein kann, werden Sie über die Ergebnisse überrascht (und oft wütend) sein, weil es nicht wirklich so funktioniert, besonders wenn es mit / verglichen oder subtrahiert wird. von vorzeichenbehafteten Werten.Antworten:
Ich vermute, Sie beziehen sich auf eine Perspektive, die von Ihren eigenen Erfahrungen geprägt ist, in der Sie nicht mit Leuten gearbeitet haben, die Integraltypen richtig verwenden. Dies mag durchaus ein häufiges Ereignis sein, aber ich habe die Erfahrung gemacht, dass die Leute sie normalerweise auch richtig anwenden.
Der Vorteil ist der Speicherplatz und die CPU-Zeit, möglicherweise auch der E / A-Speicherplatz, je nachdem, ob die Typen jemals über das Kabel oder auf eine Festplatte gesendet werden. Mit unsignierten Typen können Sie Compilerprüfungen durchführen, um sicherzustellen, dass bestimmte Operationen, die nicht möglich sind, nicht ausgeführt werden. Außerdem können Sie den verfügbaren Bereich erweitern und die kleinere Größe beibehalten, um die Leistung bei Bedarf zu steigern.
Die korrekte Verwendung ist wie man erwarten würde - wann immer Sie wissen , für bestimmte sie nutzen zu können permanent (nicht beschränken nicht ohne Sicherheit oder Sie werden es später bereuen).
public uint NumberOfPeople
), verwenden Sie einen Typ ohne Vorzeichen.public byte DamagedToothCount
) sein könnte, verwenden Sie ein Byte.public short JimmyHoffasBankBalance
).public int HoursSinceUnixEpoch
).public long MyReallyGreatAppsUserCountThisIsNotWishfulThinkingAtAll
).Diese Argumentation kann bei der Auswahl zwischen vorzeichenbehafteten, vorzeichenlosen und unterschiedlichen Schriftgrößen verwendet werden. Denken Sie nur an die logischen Wahrheiten der Daten, die Sie in der Realität darstellen.
quelle
int
überall, wenn Sie nicht wissen, dass die Problemdomäne den Wert tatsächlich einschränkt -, und keine Bank möchte die Anzahl der Konten auf 33.000 Pfund (und denkt an den Spaß) beschränken wenn das überläuft ...!).long
. Das Speichern von Speicher kann natürlich indirekt Zeit sparen, indem die Effizienz der Cache-Zeilen usw. verbessert wird, aber OTOH-Ausrichtungsprobleme bei kleinen Typen können indirekt Zeit kosten.Klar, es gibt Fälle, in denen es besser ist,
uint
odershort
oder zu verwendenInt16
. Wenn Sie wissen, dass Ihr Datenbereich in die Einschränkungen dieses Variablentyps passt, ist es in Ordnung, diesen Typ zu verwenden.In speicherbeschränkten Umgebungen oder bei der Verarbeitung großer Mengen von Objekten kann es sinnvoll sein, die kleinste Größenvariable zu verwenden. Zum Beispiel gibt es einen signifikanten Größenunterschied für ein Million-Elemente-Array von
int
s vs.short
s.In der Regel tritt dies aus einem oder mehreren der folgenden Gründe im tatsächlichen Code nicht auf:
Es gibt noch viele weitere mögliche Gründe, die sich jedoch auf Folgendes beschränken: Die Zeit, die für die Entscheidung und die Verwendung eines anderen Variablentyps erforderlich ist, hat nicht ausgereicht, um dies zu rechtfertigen.
quelle
In C wurden in Kontexten ohne ganzzahlige Heraufstufung vorzeichenlose Werte angegeben, die sich wie Mitglieder eines abstrakten algebraischen Rings "umhüllen" verhalten (also liefert XY für jedes X und Y einen eindeutigen Wert, der bei Addition zu Y X ergibt ), während vorzeichenbehaftete Integer-Typen so angegeben wurden, dass sie sich wie Ganzzahlen verhalten, wenn die Berechnungen innerhalb eines bestimmten Bereichs bleiben, und überhaupt nichts tun dürfen, wenn die Berechnungen darüber hinausgehen. Die numerische Semantik in C # ist jedoch völlig anders. Innerhalb eines überprüften numerischen Kontexts verhalten sich sowohl vorzeichenbehaftete als auch vorzeichenlose Typen wie Ganzzahlen, vorausgesetzt, die Berechnungen bleiben im Bereich und werden ausgelöst,
OverflowException
wenn dies nicht der Fall ist. In einem ungeprüften Kontext verhalten sich beide wie algebraische Ringe.In der Regel lohnt es sich nur, einen Datentyp zu verwenden, der kleiner
Int32
ist als derjenige, der zum Packen oder Auspacken von Gegenständen für eine kompakte Lagerung oder einen kompakten Transport erforderlich ist. Wenn eine halbe Milliarde positive Zahlen gespeichert werden müssen und alle im Bereich von 0 bis 100 liegen, werden durch die Verwendung von jeweils einem Byte anstelle von vier 1,5 Gigabyte Speicherplatz eingespart. Das ist eine große Ersparnis. Wenn ein Codeteil jedoch insgesamt ein paar Hundert Werte speichern muss, werden durch die Angabe eines Bytes anstelle von vier etwa 600 Bytes eingespart. Wahrscheinlich nicht lohnenswert.In Bezug auf vorzeichenlose Typen sind sie nur dann wirklich nützlich, wenn Sie den Informationsaustausch durchführen oder wenn Sie Zahlen in Teile unterteilen. Wenn beispielsweise 96-Bit-Ganzzahlen berechnet werden müssen, ist es wahrscheinlich viel einfacher, die Berechnungen für Gruppen mit drei vorzeichenlosen 32-Bit-Ganzzahlen durchzuführen, als für Gruppen mit vorzeichenbehafteten Ganzzahlen. Andernfalls gibt es nicht viele Situationen, in denen der Bereich eines vorzeichenbehafteten 32- oder 64-Bit-Werts nicht ausreichend wäre, aber die gleiche Größe eines vorzeichenlosen Werts ausreicht.
quelle
Es ist im Allgemeinen eine schlechte Idee, nicht signierte Typen zu verwenden, da diese auf unangenehme Weise überlaufen.
x = 5-6
ist plötzlich eine Zeitbombe in Ihrem Code. In der Zwischenzeit laufen die Vorteile von nicht signierten Typen auf ein einziges zusätzliches Maß an Präzision hinaus. Wenn sich das für Sie lohnt, sollten Sie mit ziemlicher Sicherheit einen größeren Typ verwenden.Es gibt Anwendungsfälle, in denen ein kleinerer Typ sinnvoll sein könnte. Wenn Sie sich jedoch keine Sorgen über die Speichernutzung machen oder Daten für die Übertragung oder die Cache-Effizienz packen müssen oder eine Handvoll anderer Probleme, ist die Verwendung eines kleineren Typs in der Regel nicht vorteilhaft . Darüber hinaus ist es bei vielen Architekturen tatsächlich langsamer , diese Typen zu verwenden, sodass sie tatsächlich geringe Kosten verursachen können.
quelle
i+1>i
in ,1
wenni
unterzeichnet, zusammen mit einer ganzen Reihe von anderen fiesen Verhalten. Ein vorzeichenloser Überlauf kann einen Fehler in einem Eckfall verursachen. Ein signierter Überlauf kann Ihr gesamtes Programm bedeutungslos machen .Wenn Sie sich speziell mit .NET-Typen befassen, wird die CLS-Kompatibilität häufig vergessen und möglicherweise als tangential für Ihre Frage angesehen . Nicht alle Typen sind für alle auf .NET Framework basierenden Sprachen verfügbar.
Wenn Sie Code für andere Sprachen als C # schreiben und sicherstellen möchten, dass dieser Code mit so vielen .NET-Sprachen wie möglich zusammenarbeitet, müssen Sie die Verwendung Ihres Typs auf CLS-kompatible Sprachen beschränken.
Beispielsweise unterstützten frühe Versionen von VB.NET (7.0 und 7.1) keine Ganzzahlen ohne Vorzeichen (
UInteger
):Ganzzahlen ohne Vorzeichen sind nicht CLS-konform und sollten daher mit Vorsicht verwendet werden, wenn Sie sich nicht sicher sind, wer Ihr Klassenbibliotheks-Consumer sein wird.
quelle