De ce este Array.Length un int, și nu un uint

De ce este Array.Length un int, și nu un uint . Acest lucru mă deranjează (doar puțin), deoarece o valoare de lungime nu poate niciodată să fie negativă.

Acest lucru ma forțat, de asemenea, să folosesc un int pentru o proprietate de lungime pe propria mea clasă, pentru că atunci când tu specificați o valoare int, aceasta trebuie exprimată în mod explicit ...

Deci, întrebarea finală este: există o utilizare pentru un int unsigned ( uint )? Chiar și Microsoft pare să nu le folosească.

0
fr hi bn
@ alan2here făcând o astfel de schimbare ar rupe aproape toate cod acolo acolo, așa că obiceiul se va întâmpla dacă mă întrebați!
adăugat autor Peter, sursa
În ciuda problemelor enunțate mai jos, cred că ar trebui să se schimbe la UInt.
adăugat autor alan2here, sursa

4 răspunsuri

De obicei, sunt semnate valori întregi, cu excepția cazului în care aveți nevoie explicit de o valoare nesemnată. Doar așa sunt folosite. Poate că nu sunt de acord cu această alegere, dar așa este.

Pentru moment, cu constrângerile de memorie tipice de astăzi, dacă structura de date matrice sau de date similare necesită o lungime UInt32, trebuie să luați în considerare și alte structuri de date.

Cu o serie de octeți, Int32 vă va oferi 2 GB de valori

0
adăugat
"dar așa este." - Nu, lucrurile nu sunt niciodată așa cum sunt. Există întotdeauna o decizie de proiectare fiind făcută și întotdeauna merită să întrebați de ce. S-ar putea să înveți ceva din argumente pro și contra sau să angajezi designerul (în unele cazuri) într-o discuție despre ei. Pune intotdeauna intrebari! :)
adăugat autor Jonas Kölker, sursa

Unsigned int nu este compatibil cu CLS și, prin urmare, ar limita utilizarea proprietății în acele limbi care implementează un UInt .

Vezi aici:

Cadrul 1.1

Introducere în Biblioteca de clasă .NET Framework

Cadrul 2.0

Privire de ansamblu asupra claselor .NET Framework

0
adăugat

Multe motive:

  • uint is not CLS compliant, thus making a built in type (array) dependent on it would have been problematic
  • The runtime as originally designed prohibits any object on the heap occupying more than 2GB of memory. Since the maximum sized array that would less than or equal to this limit would be new byte[int.MaxValue] it would be puzzling to people to be able to generate positive but illegal array lengths.
  • Historically C# inherits much of its syntax and convention from C and C++. In those arrays are simply pointer arithmetic so negative array indexing was possible (though normally illegal and dangerous). Since much existing code assumes that the array index is signed this would have been a factor
  • On a related note the use of signed integers for array indexes in C/C++ means that interop with these languages and unmanaged functions would require the use of ints in those circumstances anyway, which may confuse due to the inconsistency.
  • The BinarySearch implementation (a very useful component of many algorithms) relies on being able to use the negative range of the int to indicate that the value was not found and the location at which such a value should be inserted to maintain sorting.
  • When operating on an array it is likely that you would want to take a negative offset of an existing index. If you used an offset which would take you past the start of the array using unit then the wrap around behaviour would make your index possibly legal (in that it is positive). With an int the result would be illegal (but safe since the runtime would guard against reading invalid memory)
0
adăugat
Acest lucru este foarte informativ. În Windows Communication Foundation din .NET 4.0 - cele mai mari valori au fost 2,147,483,647 pentru maxArrayLength și maxBytesPerRead care au o semnificație retrospectivă cu aceste informații. Unind punctele...
adăugat autor Derek W, sursa
într-adevăr, dar ((uint) (int.MaxValue)) + 1 ar fi garantat greșit pentru nimic . int este în sine departe de a fi perfect, dar echilibrul de lucruri face legit să rămână cu int ca tip.
adăugat autor ShuggyCoUk, sursa
Începând să fie un tip explicit ArrayIndex (în esență size_t), care ar traduce în mod clar și în siguranță la un int după cum este necesar, probabil ar fi mai ușor în viitor să se facă cu adevărat o utilizare care să permită> 2GB arrays în viitor, cu mai puțină durere. Dar pragmaticii spun că java are aceeași problemă, de ce să-și asume riscul
adăugat autor ShuggyCoUk, sursa
Vreau doar să adaug că aritmetica C# pointer în contexte nesigure permite, de asemenea, indexuri negative. Vedeți exemplul aici: docs.microsoft.com/en -US / DOTNET / CSHARP / limbaj de referință / & hellip;
adăugat autor Mike Marynowski, sursa
Dacă nimic pe heap nu poate fi de peste 2Gb, atunci aproape toate matricile de lungime int.MaxValue sunt ilegale, deoarece cele mai multe tipuri sunt mai mari decât 1 octet.
adăugat autor ScottS, sursa

Se pare că nimeni nu a răspuns la "întrebarea ulterioară".

Cred că utilizarea primară a insignelor nesemnate este de a oferi o interfață mai ușoară cu sistemele externe (P / Invocate și altele asemenea) și pentru a acoperi necesitățile diferitelor limbi care sunt portate în .NET.

0
adăugat
Tipurile nesemnate sunt esențiale atunci când concatenăm mai multe valori mai mici pentru a produce o valoare mai mare. Se poate combina două UInt16 pentru a face un UInt32 prin calculul (HighPart << 16) + LowPart , și se poate împărți un UInt32 în două UInt16's prin (Uint16) (Value >> 16) / code> și (Uint16) (Value & 65535) . Astfel de operațiuni ar fi foarte incomod dacă LowPart trebuia să fie un tip semnat. Acestea fiind spuse, interacțiunile dintre tipurile semnate și nesemnate sunt adesea confuze și problematice. Modelele nesemnate ar treb
adăugat autor supercat, sursa