2010-07-15 9 views
8

Provengo da uno sfondo prevalentemente C/C++ prima di iniziare a usare C#. Una delle cose che ho fatto con il mio primo progetto in C# è stato fare una classe come questaPerché i tipi di CLR non firmati sono così difficili da utilizzare in C#?

class Element{ 
    public uint Size; 
    public ulong BigThing; 
} 

Sono stato poi mortificata dal fatto che questo richiede casting:

int x=MyElement.Size; 

come fa

int x=5; 
uint total=MyElement.Size+x; 

Perché i progettisti di linguaggi hanno deciso di rendere i tipi di interi senza segno e firmati non implicitamente concettabili? E perché i tipi non firmati non vengono più utilizzati in tutta la libreria .Net? Ad esempio, String.Length non può mai essere negativo, ma è un intero con segno.

+1

Anche in C++ un cast da unsigned a signed o back provoca un avviso. –

+0

@Seva a seconda del compilatore: P .. Mi rendo conto che il mio primo caso è debole, ma il mio secondo caso è davvero più quello che intendo perché non vi è alcuna possibilità di perdita dei dati lì a meno che 'x' è negativo – Earlz

+0

Sul secondo conteggio , vedi la mia risposta in basso ... –

risposta

18

Perché i progettisti di linguaggio hanno deciso di rendere implicitamente concettabili i tipi di interi con segno e senza segno non ?

Perché ciò potrebbe perdere dati o generare eccezioni, nessuna delle quali è generalmente una cosa buona da consentire implicitamente. (La conversione implicita da lungo a raddoppiare può perdere i dati troppo, è vero, ma in un modo diverso.)

E perché sono i tipi non firmati non utilizzati di più in tutta la libreria Net

tipi Unsigned non sono compatibili con CLS - non tutti i linguaggi .NET li hanno sempre supportati. Ad esempio, Visual Basic non ha il supporto "nativo" per i tipi di dati non firmati in .NET 1.0 e 1.1; è stato aggiunto alla lingua per 2.0. (Potresti ancora usarli, ma non erano parte del linguaggio stesso, ad esempio. Non utilizzare i normali operatori aritmetici, per esempio.)

+3

"anche se potrei sbagliarmi" - Vuoi dire che .NET avrebbe potuto sbagliare? – PostMan

+0

@PostMan: ho appena trovato un po 'più di informazioni ... verrà modificato. –

1

Perché la conversione implicita di un numero intero senza segno di 3B in un numero intero con segno sta andando esplodere.

Non firmato ha il doppio del valore massimo di firmato. È la stessa ragione per cui non puoi dare troppo tempo a un int.

+0

È possibile che qualcuno con una reputazione sufficiente per la modifica corregge tale da dire "intero non firmato di 3B in un numero intero con segno?" La sua intenzione era chiara, solo un refuso. –

+0

Grazie a Dave, l'ho persino riletto e l'ho perso: x –

4

Insieme alla risposta di Jon, solo perché un numero non firmato non può essere negativo, non significa che non sia più grande di quello firmato. uint è compreso tra 0 e 4.294.967.295 ma int è -2.147.483.648 a 2.147.483.647. Un sacco di spazio al di sopra dello int è il massimo.

0

Sul secondo conteggio: perché volevano che il CLR fosse compatibile con le lingue che non hanno datatype senza segno (leggi: VB.NET).

+0

VB.net ha avuto numeri non firmati almeno dal 2.0. Non ero a conoscenza della loro mancanza in precedenza, ma avrebbe molto senso - non erano in VB in tempo per farlo entrare nel CLS. – cHao

+0

Tuttavia, la modifica della classe String in .NET v2 (o, se è per questo, sempre) causerebbe la rottura di un'enorme quantità di codice. –

1

Sono stato poi mortificata dal fatto che questo richiede casting:

int x=MyElement.Size; 

Ma si sta contraddicendo qui. Se davvero (davvero) hai bisogno che Size sia unsigned piuttosto che assegnarlo a (signed) x è un errore. Un difetto profondo nel tuo codice.

Ad esempio String.Lunghezza non può mai essere negativo, ma è un intero con segno

Ma String.IndexOf può restituire un numero negativo, e sarebbe imbarazzante se i valori String.length e indice in cui di diversi tipi.

E mentre in teoria ci sarebbe il merito in uno String.length non firmato (4 GB cap), in pratica, anche l'attuale 2GB è abbastanza grande (perché le stringhe di lunghezza che sono rari e impraticabile in ogni caso).

Quindi la vera risposta è: perché utilizzare non firmato in primo luogo?

+0

Bene, perché consente un'espressione più ampia di numeri senza segno? –

+0

@Henk: Penso che un esempio migliore di dove usare 'int' è scomodo è' Array.Length'. Non ci si aspetterebbe mai che una matrice abbia una dimensione negativa e l'uso di un tipo firmato limita la dimensione (riportata) della matrice a poco meno di 2 GB. Inoltre, gli indici di array potrebbero non essere mai negativi. Ora concesso, c'è la proprietà 'LongLength' che riporta la dimensione dell'array come un' Int64' - ma lo segnala ancora come un valore firmato. La considerazione prioritaria in questi casi è il fatto che i progettisti di .NET hanno scelto di rendere i tipi non firmati non compatibili con CLS. Qualcosa che è improbabile che cambi mai a questo punto. – LBushkin

+0

@Paul: 'decimal' ha un intervallo ancora più ampio. La domanda è per _practical_ usi di unsigned. L'OP non ha fornito nessuno. –

Problemi correlati