2015-06-01 12 views

Odpowiedz

19

Rodzice niepodpisani nie są zgodni z CLS, dlatego Stream.Write nie używa uint dla przesunięcia i zliczenia.

Patrz: uint (C# Reference)

wpisać uint nie jest zgodny z CLS. Użyj int, gdy tylko jest to możliwe.

Jest to stary artykuł: Why we don't have unsigned types in the CLS by Brad Abrams (2 Sep 2003) który wyjaśnia powód:

Istnieje jednak jeden problem, który ciągle pojawia się: Dlaczego nie pozwolić niepodpisane typy (UInt32 i podobne) w CLS?

Cóż, są naprawdę dwie odpowiedzi na to pytanie. Na pierwszym poziomie niektóre języki (takie jak VB.NET) nie oferują pełnego wsparcia dla typów niepodpisanych . Na przykład nie możesz mieć niepodpisanych literałów w VB.NET .... Ale aby być uczciwym, nie jest to całkowicie satysfakcjonująca odpowiedź, ponieważ kiedy zaczęliśmy CLS, nie mogliśmy podklasy również w VB.NET , ale rozszerzyliśmy ten język, aby obsługiwać to, o czym wiedzieli ludzie. Mogliśmy zrobić to samo z typami niepodpisanymi. Ale my nie. Dlaczego nie? Cóż, to ma głębszy powód. W rzeczywistości z tego samego powodu, dla którego wczesne bety języka C# nie wspierały typów niepodpisanych (bez ushort, uint i tym podobnych).

Ogólne odczucia wśród wielu z nas jest to, że większość programowania jest wykonywana z podpisanymi typami. Za każdym razem, gdy przełączasz się na niepodpisane typy, wymuszasz zmianę modelu mentalnego na (i brzydką obsadę). W najgorszym gipsie budujesz cały równoległy świat interfejsów API, które przyjmują typy bez znaku. Wartość unikania sprawdzania "< 0" nie jest warta włączenia generycznych w CLS.

(Zauważ, że nowsza wersja VB.Net (VB 8 r) wspiera niepodpisanych typów).

Jeszcze jedno (prawdopodobnie niezwiązane) dodać, Stream.Write implementation ma kontrole dla wartości ujemnych:

[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

Z uint MSDN only

typu uint nie jest zgodny z CLS. Użyj int, gdy tylko jest to możliwe.

Tak więc Stream.Write używa int dla przesunięcia i liczby.

reasons given by ShuggyCoUk czyni go bardziej jasne:

  • uint nie jest zgodny z CLS, dzięki czemu wbudowany typu (array) od niej zależny byłby problematyczny
  • Środowisko wykonawcze jako oryginalnie zaprojektowany nie zabrania żadnego obiektu na stercie zajmującego więcej niż 1GB pamięci. Ponieważ matryca o maksymalnej wielkości, która byłaby mniejsza niż lub równa temu limitowi, byłaby nowym bajtem [int.MaxValue], byłaby to zastanawiająca dla ludzi, aby móc generować dodatnie, ale nielegalne długości tablic .
  • Historycznie C# dziedziczy wiele z jego składni i konwencji z C i C++. W tych tablicach jest po prostu arytmetyka wskaźnikowa, więc możliwe było indeksowanie tablicy negatywnej (choć zwykle nielegalne i niebezpieczne). Ponieważ wiele istniejącego kodu zakłada, że ​​indeks tablicy jest ujemny, byłby to współczynnik
  • W powiązanej notatce użycie liczb całkowitych ze znakiem dla indeksów tablic w C/C++ oznacza, że ​​współdziałanie z tymi językami i niezarządzanymi funkcjami wymagałoby w takich okolicznościach użycie ints, które może dezorientować ze względu na niespójność.
  • BinarySearch realizacja (bardzo przydatnym składnikiem wielu algorytmów) opiera się na możliwości używać negatywnego zakresu int, aby wskazać, że wartość nie stwierdzono i miejsca, w którym taka wartość powinna być wstawiony do sortować.
  • Podczas pracy na macierzy prawdopodobnie będziesz chciał uzyskać ujemne przesunięcie istniejącego indeksu. Jeśli użyłeś przesunięcia, które poprowadziłoby Cię przez początek tablicy przy użyciu jednostki , wówczas zachowanie zawijające sprawiłoby, że indeks byłby prawdopodobnie legalny (w tym sensie, że jest dodatni). Z int wynik byłby nielegalny (ale bezpieczny ponieważ środowisko wykonawcze będzie chronić przed czytania nieprawidłowy pamięci)
Powiązane problemy