Pergunta

Eu tenho o seguinte código C#:

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

o que produz o erro:

Não é possível converter implicitamente o tipo 'int' 'bytes'.Existe uma conversão explícita (está faltando uma conversão?)

[Update:primeira versão de a questão estava errado ...Eu li errado a saída do compilador]

Adicionar o elenco não corrigir o problema:

rule = rule | (byte) 0x80;

Eu preciso escrever como:

rule |= 0x80;

O que parece estranho.Qual é o |= operador diferente para o | operador?

Existe alguma outra maneira de dizer ao compilador para tratar a constante como um byte?


@ Giovanni Galbo :sim e não.O código é lidar com a programação da memória flash em um dispositivo externo, e representa logicamente um único byte de memória.Eu poderia lançá-lo mais tarde, mas este parecia mais óbvio.Eu acho que o meu C património é, mostrando através de muito muito!

@ Jonathon Holanda :o 'como' a sintaxe se parece mais puro, mas, infelizmente, não aparecem para trabalhar ...ele produz:

O operador como deve ser usado com um tipo de referência ou tipo anulável ('byte' não é um tipo de valor nulo)

Foi útil?

Solução

int rule = 0;
rule |= 0x80;

http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx O operador é definido para todos os tipos de valor.Eu acho que isso vai produziu o resultado desejado.O "|=" operador é um ou, em seguida, atribuir operador, que é simplesmente um atalho para a regra = regra | 0 x 80.

Um dos niftier coisas sobre o C# é que ele permite fazer coisas loucas como abuso tipos de valor simplesmente com base em seu tamanho.Um 'int' é exatamente o mesmo que um byte, exceto o compilador irá lançar avisos se você tentar usá-los como ambos ao mesmo tempo.Basta furar com um (neste caso, int) funciona bem.Se você está preocupado com 64bit prontidão, você pode especificar int32, mas todos os ints são int32s, mesmo correndo em x64 modo.

Outras dicas

C# não tem um literal sufixo para o byte.u = uint, l = longo, ul = ulong, f = float, m = decimal, mas nenhum byte.Você tem que lançá-lo.

Isso funciona:

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

Aparentemente, a expressão "estado | 0 x 80' retorna um int, mesmo se você definir 0x80 como 'const byte 0 x 80'.

O termo que você está procurando é "Literal" e, infelizmente, o C# não tem um byte literal.

Aqui está uma lista de todas as C# literais.

De acordo com o Especificação ECMA, pg 72 não há nenhum byte literal.Apenas inteiros literais para tipos:int, uint, long, e ulong.

Parece que você apenas terá de o fazer feio forma: http://msdn.microsoft.com/en-us/library/5bdb6693.aspx.

Quase cinco anos e ninguém na verdade, respondeu a pergunta.

Um par de respostas afirmam que o problema é a falta de um byte literal, mas isso é irrelevante.Se você calcular (byte1 | byte2) o resultado é do tipo int.Mesmo se "b" foram literalmente um sufixo para o byte, o tipo de (23b | 32b) ainda seria int.

Aceito resposta links para um artigo do MSDN, alegando que operator| é definido para todos os tipos integrais, mas isso não é verdade.

operator| não está definido no byte assim, o compilador usa a sua habitual de resolução de sobrecarga regras para escolher a versão que é definido no int.Portanto, se você quiser atribuir o resultado a uma byte você precisa lançá-lo:

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

A questão permanece, por que rule |= 0x80; trabalho?

Porque o C# especificação tem uma regra especial para o composto atribuição que lhe permite omitir a conversão explícita.No composto de atribuição de x op= y a regra é:

se o operador é um operador predefinido, se o tipo de retorno do operador seleccionado é explicitamente conversível para o tipo de x e se y é implicitamente convertido para o tipo de x ou o operador é um operador shift e, em seguida, a operação é avaliada como x = (T)(x op y), onde T é o tipo de x, exceto que x é avaliado apenas uma vez.

Infelizmente, o seu único recurso é a de fazê-lo apenas a maneira que você tem.Não há nenhum sufixo para marcar o literal como um byte.O operador | não prevê a conversão implícita como uma atribuição (por exemplo,inicialização) faria.

Aparentemente, a expressão " regra | 0 x 80' retorna um int, mesmo se você definir 0x80 como 'const byte 0 x 80'.

Eu acho que a regra é que números como 0x80 padrão int a menos que você inclua um literal sufixo.Assim, para a expressão rule | 0x80, o resultado será um inteiro desde 0x80 é um int e a regra (o que é um byte) pode ser convertido para int.

De acordo com o padrão de C, bytes promover SEMPRE a int em expressões, mesmo que constantes.No entanto, desde que ambos os valores não são ASSINADOS, os bits de ordem alta será descartada para a operação deve retornar o valor correto.

Da mesma forma, flutua promover a dupla, etc.

Retire da cópia do K&R.Está tudo lá.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top