Domanda

    

Questa domanda ha già una risposta qui:

    
            
  •              Spostamento bit sinistro 255 (come byte)                                      7 risposte                          
  •     
    

Ho questo codice.

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

Quando provo a compilare ottengo:

  

Impossibile convertire implicitamente il tipo 'int'   a "byte". Una conversione esplicita   esiste (ti manca un cast?)

Perché succede? Non dovrei | due byte danno un byte? Entrambi i seguenti lavori, assicurando che ogni elemento è un byte.

Encoding.ASCII.GetString(new byte[] { (dup) });
Encoding.ASCII.GetString(new byte[] { (0x80) });
È stato utile?

Soluzione

È così in base alla progettazione in C # e, di fatto, risale al C / C ++ - quest'ultimo promuove anche gli operandi in int, di solito non si nota perché int -> char la conversione è presente implicito, mentre non è in C #. Questo non vale solo per |, ma per tutti gli operandi aritmetici e bit a bit - ad es. l'aggiunta di due byte ti darà anche un (byte)200 + (byte)100. Citerò la parte pertinente delle specifiche qui:

  

Si verifica una promozione numerica binaria per   gli operandi del predefinito +, & # 8211 ;,   *, /,%, & amp ;, |, ^, ==,! =, > ;, < ;, > = e < = operatori binari . Binario   la promozione numerica si converte implicitamente   entrambi gli operandi in un tipo comune che,   in caso di non relazione   operatori, diventa anche il risultato   tipo di operazione. Numerico binario   la promozione consiste nell'applicare il   seguendo le regole, nell'ordine in cui   appare qui:

     
      
  • Se uno degli operandi è di   digitare decimale, l'altro operando è   convertito in tipo decimale o a   errore di compilazione si verifica se l'altro   l'operando è di tipo float o double.

  •   
  • Altrimenti, se uno degli operandi è di   digitare double, l'altro operando è   convertito in tipo double.

  •   
  • In caso contrario,   se uno degli operandi è di tipo float,   l'altro operando viene convertito in tipo   galleggiante.

  •   
  • Altrimenti, se uno degli operandi   è di tipo ulong, l'altro operando lo è   convertito in tipo ulong o a   errore di compilazione si verifica se l'altro   l'operando è di tipo sbyte, short, int,   o lungo.

  •   
  • Altrimenti, se uno dei due   l'operando è di tipo long, l'altro   l'operando viene convertito in type long.

  •   
  • Altrimenti, se uno degli operandi è di   digitare uint e l'altro operando è di   digitare sbyte, short o int, entrambi   gli operandi vengono convertiti in type long.

  •   
  • Altrimenti, se uno degli operandi è di   digitare uint, l'altro operando è   convertito in type uint.

  •   
  • In caso contrario,   entrambi gli operandi vengono convertiti in tipo   Int.

  •   

Non conosco la logica esatta per questo, ma posso pensarne uno. Soprattutto per gli operatori aritmetici, potrebbe essere un po 'sorprendente per le persone ottenere 44 improvvisamente uguale a <=>, anche se ha un senso se si considerano attentamente i tipi coinvolti. D'altra parte, <=> è generalmente considerato un tipo che è & Quot; abbastanza buono & Quot; per l'aritmetica sui numeri più tipici, quindi promuovendo entrambi gli argomenti su <=>, ottieni una sorta di " funziona solo " comportamento per i casi più comuni.

Per quanto riguarda il motivo per cui questa logica è stata applicata anche agli operatori bit a bit - immagino che ciò sia dovuto principalmente alla coerenza. Il risultato è una singola semplice regola comune per tutti tipi binari non booleani.

Ma questo è tutto per lo più indovinante. Eric Lippert sarebbe probabilmente il solo a chiedere quali fossero i veri motivi alla base di questa decisione per C # (anche se sarebbe un po 'noioso se la risposta fosse semplicemente & Quot; è come si fa in C / C ++ e Java, e è una regola abbastanza buona così com'è, quindi non abbiamo visto alcun motivo per cambiarlo ").

Altri suggerimenti

Il letterale 0x80 ha il tipo " int " ;, quindi non stai inserendo byte.

Che puoi passarlo al byte [] funziona solo perché 0x80 (come letterale) è compreso nell'intervallo di byte.

Modifica : anche se 0x80 viene trasmesso su un byte, il codice non verrà comunque compilato, poiché i byte di ordinamento restituiranno comunque int. Per averlo compilato, è necessario eseguire il cast del risultato o: (byte)(0x80|dup)

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

Il risultato di un bit per bit Or (|) su due byte è sempre un int.

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