ti-enxame.com

Conversão de bytes int em C #

Porque é

byte someVar;
someVar -= 3; 

válido mas

byte someVar;
someVar = someVar - 3;

não é?

28
Dested

Surpreendentemente, quando você executa operações em bytes, os cálculos serão feitos usando os valores int, com os bytes implicitamente convertidos em (int) primeiro. Isso também é válido para shorts e da mesma forma floats são convertidos para double ao fazer aritmética de ponto flutuante.

O segundo trecho é equivalente a:

byte someVar;
someVar = (int) someVar - 3;

Por isso, você deve converter o resultado de volta para (byte) para fazer o compilador aceitar a atribuição.

someVar = (byte) (someVar - 3);
30
John Kugelman

Aqui está uma cópia de uma tabela na especificação da CLI (Ecma 335) que especifica quais operandos são válidos nos operadores numéricos binários do tipo A op B, onde A e B são os operandos e "op" é o operador, como Opcodes. Sub que você está usando no seu snippet:

alt text

Algumas anotações são necessárias com isso:

  • "native int" é IntPtr em um programa C #
  • F representa um tipo de ponto flutuante, duplo ou flutuante em C #
  • & representa um valor de ponteiro, as caixas são sombreadas porque são operações inseguras
  • O representa uma referência de objeto
  • x é uma operação que não é permitida.

Observe a linha e a coluna para F , ambos os operandos devem ser de ponto flutuante; você não pode adicionar diretamente, por exemplo, um int a um duplo. O compilador C # lida com essa limitação convertendo automaticamente o operando int para o dobro, para que o operador seja válido.

Relevante para sua pergunta: observe também que os tipos de byte, sbyte, char, curto e ushort não estão presentes. Da mesma maneira, o compilador converte os operandos no menor tipo que pode representar o valor, para que o operador possa ser usado. Qual será int32. De acordo com a tabela, o resultado da operação será int32.

Agora, aqui está o problema: o resultado é int32, mas atribuir isso de volta a um valor de byte requer uma conversão restritiva. De 32 bits a 8 bits. Isso é problema, porque perde bits significativos. O compilador C # exige que você explique isso. Você essencialmente reconhece que sabe o que está fazendo e que está ciente do resultado potencialmente surpreendente. Como este:

byte v = 255;
v = (byte)(v + 1);

O operador - = é um problema porque não há uma maneira eficaz de aplicar essa conversão necessária. Não é expressável na sintaxe do idioma. Usar (byte) 3 não faz sentido, o literal é convertido em int32 para fazer o operador funcionar.

Eles resolveram o problema, o compilador emite automaticamente o elenco sem a sua ajuda.

11
Hans Passant