2015-06-16 15 views
5

Sto provando a creare un List<byte> da un file che contiene string (esadecimale). la definizione è:Aggiungi esadecimale dal file all'elenco <byte>

List<byte> myArray = new List<byte>(); 

se voglio aggiungere il mio informazioni direttamente Io uso qualcosa di simile:

myArray.Add(0xb8); 

Nota: Senza alcun preventivo o doppia citazione.

Il problema è quando voglio fare la stessa cosa dal file! Ora voglio sapere che tipo 0xb8 s' è quindi utilizzare il seguente codice:

0xc3.GetType().ToString() 

il risultato è: System.Int32 !!!!

ma quando leggo le stringhe da un file e uso un codice come questo, mi dà il seguente errore.

codice:

Line = "0xb8"; 
myArray.Add(Convert.ToInt32(Line)); 

Errore:

Argument 1: cannot convert from 'int' to 'byte' 

ed è chiaro. perché l'unico sovraccarico di myArray ottiene solo uno byte come argomento. Ciò che rende la cosa così complicata per me è il motivo per cui non mi dà alcun errore quando aggiungo uno a myArray in myArray.Add(0xb8);.

Penso che dovrebbe essere una forma di byte! può essere !

Perché non fornisce errori e come è possibile eseguire questo scenario (intendo aggiungere byte da stringa a myArray)?

+0

'il risultato è: System.Int32 !!!! 'certo ... un numero. Cos'altro potrebbe essere? – edc65

risposta

2

È possibile liberarsi di tale errore del compilatore semplicemente casting del valore di byte:

myArray.Add((byte)Convert.ToInt32(Line)); 

Tuttavia, quando si esegue il codice che si otterrà un errore diverso:

Unhandled Exception: System.FormatException: Input string was not in a correct format.

Questo perché il metodo Convert.ToInt32 non analizza i numeri esadecimali fuori dalla scatola.

È possibile specificare la base quando si converte la stringa in un numero:

myArray.Add((byte)Convert.ToInt32(Line, 16)); 
+0

Oppure puoi salvare te stesso il cast e usare 'Convert.ToByte (Line, 16)' invece ... poi se ti capita di fornire un 'Line' di" 0xF8C4 "puoi prendere un' OverflowException' invece di semplicemente troncando tranquillamente a 0xC4 – Sabre

2

How can accomplish this scenario (I mean add byte from string to myArray) ?

List<byte> myArray = new List<byte>(); 
string Line = "0xb8"; 
myArray.Add(Convert.ToByte(Line, 16)); 

why it doesn't give me any error when I add a Int32 to myArray in myArray.Add(0xb8);

compilatore può vedere che 0xb8 è in Byte valori possono variare

myArray.Add(0xb8); // ok 
myArray.Add(0xff); // ok 
myArray.Add(0x100); // cannot convert from int to byte 
4

0xb8 è un letterale intero (come 1234). "0xb8" è una stringa letterale (come "x"). Non esiste una letterale esadecimale in C#. È un letterale int in formato esadecimale. Questo spiega il problema che hai avuto con i letterali.

Non tutte le funzioni di analisi delle stringhe supportano l'input esadecimale. Vedi this for how to parse a hex string.

Quando una funzione di analisi fornisce un int ed è necessario trattarlo come byte, è possibile eseguire il cast: (byte)myInt. Questo è sicuro perché il valore analizzato è garantito per adattarsi a un byte.

In alcuni punti il ​​compilatore è in grado di eseguire automaticamente la conversione per te se hai utilizzato una costante come 0xb8. Dal momento che non lo avrai in pratica (stai analizzando un file) quel caso non è rilevante per il codice finale. Ma questo spiega perché funzioni.

+1

il suo problema è che c'è qualche intelligenza nel compilatore in modo che i letterali integrali siano convertiti nel tipo giusto dal compilatore ... – xanatos

+0

@xanatos a destra. * Molte * cose da spiegare qui! Che problema sorprendentemente confuso per un principiante. – usr

5

Questo funziona:

var list = new List<byte>(); 

byte byteValue = 0xb8; 
list.Add(byteValue); 

Questo non ("non può convertire da 'int' a 'byte'"):

var list = new List<byte>(); 

int byteValue = 0xb8; 
list.Add(byteValue); 

Eppure, in entrambi i casi 0xb8 è riconosciuto come System.Int32. Quindi, perché il compilatore consente la conversione implicita di un int a byte nel primo esempio?

See C# spec 6.1.9 impliciti costanti conversioni espressione:

A constant-expression (§7.19 [including literals]) of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant-expression is within the range of the destination type.

Questo esiste perché tutti gli interi sono o (u)int o (u)long, come specificato in 2.4.4.2 letterali interi.

Dato il 0 <= 0xb8 <= 255, il compilatore consente la conversione implicita.

Nel tuo caso, a causa di motivi explained by @usr, avrete bisogno di fare una conversione esplicita:

myArray.Add((byte)Convert.ToInt32(Line, 16)); 
+2

sì, grazie. hai ragione –