Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

         

Tengo este código.

byte dup = 0;
Encoding.ASCII.GetString(new byte[] { (0x80 | dup) });

Cuando intento compilar obtengo:

  

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

¿Por qué sucede esto? No debería | dos bytes dan un byte? Los dos trabajos siguientes aseguran que cada elemento sea un byte.

Encoding.ASCII.GetString(new byte[] { (dup) });
Encoding.ASCII.GetString(new byte[] { (0x80) });
¿Fue útil?

Solución

Es así por diseño en C # y, de hecho, se remonta a C / C ++; este último también promueve operandos a int, por lo general no se nota porque hay una conversión int -> char implícito, mientras que no está en C #. Esto no solo se aplica a | tampoco, sino a todos los operandos aritméticos y bit a bit, p. agregar dos byte s también le dará un (byte)200 + (byte)100. Citaré la parte relevante de la especificación aquí:

  

Se produce promoción numérica binaria para   los operandos de los predefinidos +, & # 8211 ;,   *, /,%, & amp ;, |, ^, ==,! =, > ;, < ;, > =, y < = operadores binarios . Binario   la promoción numérica convierte implícitamente   ambos operandos a un tipo común que,   en caso de no relacional   operadores, también se convierte en el resultado   tipo de la operación. Numérico binario   la promoción consiste en aplicar el   siguiendo las reglas, en el orden en que   aparece aquí:

     
      
  • Si cualquiera de los operandos es de   escriba decimal, el otro operando es   convertido a tipo decimal, o un   se produce un error en tiempo de compilación si el otro   el operando es de tipo flotante o doble.

  •   
  • De lo contrario, si cualquiera de los operandos es de   escriba double, el otro operando es   convertido a tipo doble.

  •   
  • De lo contrario,   si cualquiera de los operandos es de tipo flotante,   el otro operando se convierte a tipo   flotador.

  •   
  • De lo contrario, si cualquiera de los operandos   es de tipo ulong, el otro operando es   convertido a tipo ulong, o un   se produce un error en tiempo de compilación si el otro   el operando es de tipo sbyte, short, int,   o largo.

  •   
  • De lo contrario, si   operando es de tipo largo, el otro   el operando se convierte a tipo largo.

  •   
  • De lo contrario, si cualquiera de los operandos es de   escriba uint y el otro operando es de   escriba sbyte, short o int, ambos   los operandos se convierten a tipo largo.

  •   
  • De lo contrario, si cualquiera de los operandos es de   escriba uint, el otro operando es   convertido a tipo uint.

  •   
  • De lo contrario,   ambos operandos se convierten a tipo   int.

  •   

No sé la razón exacta de esto, pero puedo pensar en uno. Especialmente para los operadores aritméticos, puede ser un poco sorprendente para las personas obtener 44 de repente igual a <=>, incluso si tiene algún sentido cuando uno considera cuidadosamente los tipos involucrados. Por otro lado, <=> generalmente se considera un tipo que es & Quot; suficientemente bueno & Quot; para la aritmética en la mayoría de los números típicos, por lo que al promover ambos argumentos a <=>, obtienes una especie de & "; simplemente funciona &"; comportamiento para los casos más comunes.

En cuanto a por qué esta lógica también se aplicó a los operadores bit a bit, me imagino que esto es principalmente por coherencia. Da como resultado una sola regla simple que es común para todos tipos binarios no booleanos.

Pero todo esto es principalmente adivinar. Eric Lippert probablemente sea el que pregunte sobre los motivos reales detrás de esta decisión para C # al menos (aunque sería un poco aburrido si la respuesta es simplemente & "; Así es como se hace en C / C ++ y Java, y es una regla lo suficientemente buena como es, así que no vimos ninguna razón para cambiarla ").

Otros consejos

El literal 0x80 tiene el tipo " int " ;, por lo que no está ordeando bytes.

Que puede pasarlo al byte [] solo funciona porque 0x80 (como literal) está dentro del rango del byte.

Editar : incluso si 0x80 se convierte a un byte, el código aún no se compilaría, ya que oring bytes aún dará int. Para que se compile, el resultado de o debe ser emitido: (byte)(0x80|dup)

byte dup = 0;
Encoding.ASCII.GetString(new byte[] { (byte)(0x80 | dup) });

El resultado de un bit a bit (|) en dos bytes es siempre un int.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top