Domanda
Ho il seguente codice C#:
byte rule = 0;
...
rule = rule | 0x80;
che produce l'errore:
Impossibile convertire implicitamente il tipo "int" in "byte".Esiste una conversione esplicita (ti manca un cast?)
[Aggiornamento:la prima versione della domanda era sbagliata...Ho letto male l'output del compilatore]
Aggiunta del cast no risolvi il problema:
rule = rule | (byte) 0x80;
Devo scriverlo come:
rule |= 0x80;
Il che sembra strano.Perché è il |=
operatore diverso da quello |
operatore?
Esiste un altro modo per dire al compilatore di trattare la costante come un byte?
@Giovanni Galbo :sì e no.Il codice riguarda la programmazione della memoria flash in un dispositivo esterno e rappresenta logicamente un singolo byte di memoria.Avrei potuto lanciarlo più tardi, ma questo sembrava più ovvio.Immagino che la mia eredità C sia evidente troppo!
@ Jonathon Olanda :la sintassi "as" sembra più ordinata ma sfortunatamente non sembra funzionare ...produce:
L'operatore as deve essere utilizzato con un tipo di riferimento o un tipo nullable ('byte' è un tipo di valore non nullable)
Soluzione
int rule = 0;
rule |= 0x80;
http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx Il | L'operatore è definito per tutti i tipi di valore.Penso che questo produrrà il risultato desiderato.L'operatore "| =" è un operatore o quindi assegnare, che è semplicemente stenografia per regola = regola | 0x80.
Una delle cose più belle di C# è che ti consente di fare cose folli come i tipi di valore di abuso semplicemente in base alla loro dimensione.Un 'int' è esattamente uguale a un byte, tranne per il fatto che il compilatore lancerà degli avvisi se provi a utilizzarli come entrambi allo stesso tempo.Attenersi semplicemente a uno (in questo caso, int) funziona bene.Se sei preoccupato per la disponibilità a 64 bit, puoi specificare int32, ma tutti gli int sono int32, anche in esecuzione in modalità x64.
Altri suggerimenti
C# non ha un suffisso letterale per byte.u = uint, l = long, ul = ulong, f = float, m = decimale, ma nessun byte.Devi lanciarlo.
Funziona:
rule = (byte)(rule | 0x80);
Apparentemente la regola dell'espressione | 0x80 'restituisce un int anche se si definisce 0x80 come "const byte 0x80".
Il termine che stai cercando è "Literal" e sfortunatamente C# non ha un byte letterale.
Ecco un elenco di tutti i valori letterali C#.
Secondo il Specifiche ECMA, pagina 72 non esiste un byte letterale.Solo valori letterali interi per i tipi:int, uint, lungo e ulong.
Sembra che potresti dover farlo nel modo brutto: http://msdn.microsoft.com/en-us/library/5bdb6693.aspx.
Sono passati quasi cinque anni e nessuno ha effettivamente risposto alla domanda.
Un paio di risposte affermano che il problema è la mancanza di un byte letterale, ma questo è irrilevante.Se calcoli (byte1 | byte2)
il risultato è di tipo int
.Anche se "b" fosse un suffisso letterale per il byte di tipo (23b | 32b)
lo sarebbe ancora int
.
La risposta accettata si collega a un articolo MSDN che lo afferma operator|
è definito per tutti i tipi integrali, ma neanche questo è vero.
operator|
non è definito su byte
quindi il compilatore usa le consuete regole di risoluzione dell'overload per scegliere la versione su cui è definita int
.Quindi, se vuoi assegnare il risultato ad a byte
devi lanciarlo:
rule = (byte)(rule | 0x80);
La domanda rimane: perché lo fa rule |= 0x80;
lavoro?
Perché la specifica C# prevede una regola speciale per l'assegnazione composta che consente di omettere la conversione esplicita.Nell'incarico composto x op= y
la regola è:
se l'operatore selezionato è un operatore predefinito, se il tipo restituito dell'operatore selezionato è esplicitamente convertibile nel tipo x e se y è implicitamente convertibile nel tipo x o l'operatore è un operatore di spostamento, l'operazione viene valutata COME
x = (T)(x op y)
, dove T è il tipo di x, tranne per il fatto che x viene valutato solo una volta.
Sfortunatamente, la tua unica possibilità è farlo proprio come hai fatto.Non esiste un suffisso per contrassegnare il valore letterale come byte.Il | L'operatore non prevede una conversione implicita come incarico (cioèinizializzazione) sarebbe.
Apparentemente la regola dell'espressione | 0x80 'restituisce un int anche se si definisce 0x80 come "const byte 0x80".
Penso che la regola sia che numeri come 0x80 abbiano come valore predefinito int a meno che non si includa un suffisso letterale.Quindi per l'espressione rule | 0x80
, il risultato sarà un int poiché 0x80 è un int e la regola (che è un byte) può essere tranquillamente convertita in int.
Secondo lo standard C, i byte promuovono SEMPRE a int nelle espressioni, anche nelle costanti.Tuttavia, finché entrambi i valori sono UNSIGNED, i bit di ordine superiore verranno scartati, quindi l'operazione dovrebbe restituire il valore corretto.
Allo stesso modo, i float promuovono al raddoppio, ecc.
Estrarre la copia di K&R.È tutto lì dentro.