Wydaje mi się wysoce nielogiczne, że Stream.Write używa int
, zamiast ... Czy istnieje wyjaśnienie inne niż "starsza" kod dla tego faktu? Czy ktokolwiek chciałby napisać -1
bajtów?!?Dlaczego Stream.Write nie pobiera UInt?
Odpowiedz
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"));
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 .
- Należy pamiętać, że ograniczenie to zostało zmienione na somewhat removed in the 4.5 release, , ale pozostaje standardowa długość jako int.
- 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)
Wierzcie lub nie, są liczbami całkowitymi bez znaku not part of the Common Language Specification (CLS).
TYP uint nie jest zgodny z CLS. Użyj int, gdy tylko jest to możliwe.
Zatem Microsoft używane int
tutaj zamiast uint
w interesie CLS potwierdzający zgodność.