2015-06-01 15 views

Antwort

19

Vorzeichenlose Typen sind nicht CLS-konform, daher verwendet Stream.Writeuint 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")); 
5

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)
Verwandte Themen