Es scheint mir sehr unlogisch, dass Stream.Write verwendet int
statt UInt
... Gibt es eine andere Erklärung als "Legacy" Code für diese Tatsache? Möchte jemand -1
Bytes schreiben?!?Warum nimmt Stream.Write kein UInt?
Antwort
Vorzeichenlose Typen sind nicht CLS-konform, daher verwendet Stream.Write
uint
nicht für Offset und Anzahl.
Siehe: uint (C# Reference)
Die uint-Typ ist nicht CLS-kompatibel. Verwenden Sie int wann immer möglich.
Es gibt einen alten Artikel: Why we don't have unsigned types in the CLS by Brad Abrams (2 Sep 2003), dass der Grund erklärt:
Allerdings gibt es ein Problem, das kommen hält: Warum haben wir erlauben nicht unsigned Typen (UInt32 und dergleichen) in der CLS?
Nun, es gibt wirklich zwei Antworten auf diese Frage. Auf der ersten Ebene einige Sprachen (wie VB.NET) bieten keine volle Unterstützung für unsigned Typen. Zum Beispiel können Sie keine unsignierten Literale in VB.NET ... haben. Aber um fair zu sein, das ist keine vollständig befriedigende Antwort , denn als wir das CLS starteten, konnte man keine Unterklasse in VB.NET entweder, aber wir erweiterten diese Sprache, um das zu unterstützen, was wir Leute wüssten, würde wollen. Mit unsignierten Typen hätten wir das Gleiche machen können. Aber wir haben nicht. Warum nicht? Nun, das bekommt einen tieferen Grund. In der Tat der gleiche Grund, warum frühe Betas der Sprache C# unsigned Typen (keine Ushort, Uint und dergleichen) nicht unterstützt.
Das allgemeine Gefühl unter vielen von uns ist, dass die überwiegende Mehrheit der Programmierung ist mit signierten Typen getan. Wann immer Sie zu vorzeichenlosen Typen wechseln, erzwingen Sie einen mentalen Modellwechsel (und eine hässliche Besetzung). In der schlechtesten Besetzung bauen Sie eine ganze parallele Welt von APIs, die unsigned Typen nehmen. Der Wert der Vermeidung der "< 0" Prüfung ist nicht die Aufnahme von Generika in der CLS wert.
(Beachten Sie, dass neuere Version von VB.Net (VB 8 ab) unsigned Typen unterstützt).
Eine weitere Sache (wahrscheinlich nicht verwandten) hinzuzufügen, hat Stream.Write
implementation prüft, ob negative Werte:
[System.Security.SecuritySafeCritical] // auto-generated
public override void Write(byte[] array, int offset, int count) {
if (array==null)
throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (array.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Vom uint MSDN only
Die uint-Typ nicht CLS-kompatibel ist. Verwenden Sie int wann immer möglich.
So verwendet Stream.Write
Int für Offset und Count.
Die reasons given by ShuggyCoUk macht es klar:
- uint nicht CLS-kompatibel ist, so dass eine in Art (Array) aufgebaut abhängig zu machen, es würde
- Die Laufzeit als ursprünglich problematisch gewesen entworfen verbietet jedes Objekt auf dem Heap mehr als 2 GB Speicher. Da die maximale Größe Array, das würde weniger als oder gleich diese Grenze neue Byte wäre [int.MaxValue] es seien zu Menschen rätselhaft in die Lage positiv, aber illegal Array Längen zu erzeugen.
- Beachten Sie, dass diese Beschränkung somewhat removed in the 4.5 release, ist, obwohl die Standardlänge als int bleibt.
- Historisch C# erbt viel seiner Syntax und Konvention von C und C++. In diesem Arrays sind einfach Pointer-Arithmetik so negativ Array-Indizierung möglich war (obwohl normalerweise illegal und gefährlich). Da viel existierender Code davon ausgeht, dass der Array-Index negativ ist, wäre dies ein Faktor
- Auf eine verwandte Anmerkung bedeutet die Verwendung von Ganzzahlen mit Vorzeichen für Array-Indizes in C/C++, dass Interop mit diesen Sprachen und nicht verwalteten Funktionen erfordern würde Verwendung von Ints unter diesen Umständen sowieso, die aufgrund der Inkonsistenz verwirren können.
- Die Binary Implementierung (eine sehr nützliche Komponente vieler Algorithmen) zu auf in der Lage beruht wurde die negative Bereich des int verwenden, um anzuzeigen, dass der Wert nicht und, an dem der Standort gefunden ein solcher Wert sein sollte eingefügt in Sortierung beibehalten.
- Wenn auf einem Array arbeitet, ist es wahrscheinlich, dass Sie eine negative eines bestehenden Index-Offset zu übernehmen möchte. Wenn Sie verwendet ein Offset, die Sie vorbei an den Anfang des Arrays würde Einheit mit dann die Wrap-around-Verhalten würde Ihr Index möglicherweise rechtliche (in, dass es positiv ist) machen. Mit einem int wäre das Ergebnis ungültig sein (aber sicher, da die Laufzeit gegenüber dem Ablesen ungültige Speicher schützen würde)
Ob Sie es glauben oder nicht, ganze Zahlen ohne Vorzeichen sind not part of the Common Language Specification (CLS).
Die uint-Typ nicht CLS-kompatibel ist. Verwenden Sie int wann immer möglich.
So verwendet Microsoft int
hier statt uint
im Interesse der CLS-Kompatibilität.
- 1. Warum ist Array.count kein UInt?
- 2. Typeerror: Objekt() nimmt kein Parameter
- 3. Warum nimmt Array.prototype.reduce() kein leeres Array als Akkumulator an?
- 4. Ist Stream.Write Thread-sicher?
- 5. Unterschied von zwei 'uint'
- 6. Warum nimmt TR keinen Stil?
- 7. Warum Haskell ein Argument nimmt
- 8. Warum nimmt TaskSpawn statt void *?
- 9. Warum nimmt Arrays.sort Object [] anstatt Comparable []?
- 10. Konvertieren von enum in uint
- 11. Ist Uint strikt positiv
- 12. Wie reserviere ich mehr Platz mit Stream.Write?
- 13. Warum nimmt Python lxml meine XML nicht?
- 14. Warum kann ich einen int nicht von einem uint subtrahieren?
- 15. Warum bekomme ich keine Ausnahme für Ganzzahl (Uint) unter/Überlauf?
- 16. Warum nimmt JavaScript diesen Fehler nicht auf?
- 17. Warum nimmt `execvp` ein` char * const argv [] `?
- 18. Warum ein SWITCH ... CASE nicht "char" nimmt?
- 19. Warum nimmt Moose's Builder einen String-Wert?
- 20. Warum nimmt Drop & mut self statt selbst?
- 21. Warum nimmt numpy.find_common_type zwei separate Listen an?
- 22. Warum nimmt CompositionTarget.Rendering anstelle von RenderingEventArgs EventArgs?
- 23. Warum nimmt RazorViewEngine meine DisplayTemplate nicht an?
- 24. Warum nimmt IPAddress-Konstruktor Int64 statt UInt32?
- 25. konvertieren ganze byte [] in uint
- 26. Warum nicht die Instanzvariable nimmt den neuen Wert
- 27. Warum nimmt der Compiler an, dass malloc einen int zurückgibt?
- 28. Warum nimmt mein GridSplitter nicht die volle Höhe an?
- 29. Verhindern, dass Text von stream.write() in Node.js überschrieben wird
- 30. Swift: Wie konvertiert man String in UInt?