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)

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top