type operator objetos convert cast another c# casting

operator - Constantes numéricas de C#



casting de objetos en c# (10)

Tengo el siguiente código de C #:

byte rule = 0; ... rule = rule | 0x80;

que produce el error:

No se puede convertir implícitamente el tipo ''int'' a ''byte''. Existe una conversión explícita (¿falta un elenco?)

[Actualización: la primera versión de la pregunta era incorrecta ... Leí mal la salida del compilador]

Agregar el elenco no soluciona el problema:

rule = rule | (byte) 0x80;

Necesito escribirlo como:

rule |= 0x80;

Lo cual parece extraño. ¿Por qué el operador |= diferente al | ¿operador?

¿Hay alguna otra manera de decirle al compilador que trate la constante como un byte?

@ Giovanni Galbo : sí y no. El código trata de la programación de la memoria flash en un dispositivo externo y, lógicamente, representa un solo byte de memoria. Podría lanzarlo más tarde, pero esto parecía más obvio. ¡Creo que mi herencia de C se muestra demasiado!

@ Jonathon Holland : la sintaxis "como" parece más ordenada, pero desafortunadamente no parece funcionar ... produce:

El operador as se debe usar con un tipo de referencia o tipo anulable (''byte'' es un tipo de valor que no admite nulos)


El término que está buscando es "Literal" y lamentablemente C # no tiene un literal de bytes.

Aquí hay una lista de todos los literales de C # .


Al parecer, la expresión ''regla | 0x80 ''devuelve un int incluso si define 0x80 como'' const byte 0x80 ''.

Creo que la regla es números como 0x80 por defecto a int a menos que incluya un sufijo literal. Entonces, para la rule | 0x80 expresión rule | 0x80 rule | 0x80 , el resultado será un int ya que 0x80 es una int y la regla (que es un byte) se puede convertir de forma segura a int.


C # no tiene un sufijo literal para byte. u = uint, l = largo, ul = ulong, f = flotante, m = decimal, pero no byte. Tienes que lanzarlo.



Desafortunadamente, tu único recurso es hacerlo de la manera que tienes. No hay sufijo para marcar el literal como un byte. El | el operador no proporciona la conversión implícita como lo haría una asignación (es decir, la inicialización).


Esto funciona:

rule = (byte)(rule | 0x80);

Al parecer, la expresión ''regla | 0x80 ''devuelve un int incluso si define 0x80 como'' const byte 0x80 ''.



int rule = 0; rule |= 0x80;

http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx El | operador se define para todos los tipos de valores. Creo que esto producirá el resultado deseado. El operador "| =" es un operador o luego asigna, que es simplemente una abreviatura de regla = regla | 0x80.

Una de las cosas más importantes acerca de C # es que te permite hacer cosas locas como tipos de valor de abuso basados ​​simplemente en su tamaño. Un ''int'' es exactamente lo mismo que un byte, excepto que el compilador lanzará advertencias si lo intenta y las usa como ambas al mismo tiempo. Simplemente quedarse con uno (en este caso, int) funciona bien. Si le preocupa la preparación de 64 bits, puede especificar int32, pero todas las entradas son int32s, incluso se ejecutan en modo x64.


De acuerdo con el estándar C, los bytes SIEMPRE promueven a int en expresiones, incluso constantes. Sin embargo, mientras ambos valores estén DESIGNADOS, los bits de orden superior se descartarán para que la operación devuelva el valor correcto.

Del mismo modo, las carrozas promueven al doble, etc.

Saque la copia de K & R. Todo está ahí.


Casi cinco años después y nadie ha respondido la pregunta.

Un par de respuestas afirman que el problema es la falta de un byte literal, pero esto es irrelevante. Si calcula (byte1 | byte2) el resultado es de tipo int . Incluso si "b" fuera un sufijo literal para byte, el tipo de (23b | 32b) seguiría siendo int .

La respuesta aceptada se vincula a un artículo de MSDN que afirma que el operator| se define para todos los tipos integrales, pero esto tampoco es cierto.

operator| no está definido en byte por lo que el compilador usa sus reglas de resolución de sobrecarga habituales para elegir la versión que está definida en int . Por lo tanto, si quiere asignar el resultado a un byte , necesita lanzarlo:

rule = (byte)(rule | 0x80);

La pregunta sigue siendo, ¿por qué la rule |= 0x80; ¿trabajo?

Porque la especificación C # tiene una regla especial para la asignación compuesta que le permite omitir la conversión explícita. En la asignación compuesta x op= y la regla es:

si el operador seleccionado es un operador predefinido, si el tipo de devolución del operador seleccionado es explícitamente convertible al tipo de x, y si y es implícitamente convertible al tipo de x o el operador es un operador de desplazamiento, entonces la operación se evalúa como x = (T)(x op y) , donde T es el tipo de x, excepto que x se evalúa solo una vez.