2015-11-27 11 views
15

Considerate questo codice:In che modo C# sa di che tipo è il letterale?

double i = 0xF0000000; 
Console.WriteLine(0xF0000000.GetType()); 
Console.WriteLine(i.GetType()); 

Perché C# stampa System.UInt32 per primo e System.Double per il secondo?

È perché, per impostazione predefinita, il compilatore deduce un valore letterale di tipo var?

+53

Non c'è alcun tipo 'var'. –

risposta

57

In questa linea:

double i = 0xF0000000; 

il letterale è di tipo uint, ma è in fase di implicitamente convertito double. Quando si chiama i.GetType() che avrebbe sempre stampa System.Double, perché la variabile è di tipo double ... l'unica tipo di valore che può contenere è un double.

Si noti che questa conversione a double significa che si può perdere di precisione, se si inizia con un long o ulong. Per esempio:

using System; 

public class Program 
{ 
    static void Main() 
    { 
     long x = 123456789; 
     double y = 123456789; 
     Console.WriteLine(x.ToString("n")); 
     Console.WriteLine(y.ToString("n")); 
    } 
} 

stampe

123,456,789,012,345,678.00 
123,456,789,012,346,000.00 

Si noti come le poche cifre finali si perdono nella double, perché la conversione implicita long-double può perdere di precisione. (Entrambi hanno 64 bit disponibili, ma solo double alcuni di questi bit vengono utilizzati per la mantissa.)

Non è un problema per int o uint letterali, ma vale la pena di essere consapevole che la conversione avviene.

12

In base a Integer Literals (C#) il tipo di un valore letterale intero dipende dal valore e dal relativo suffisso.

  • Se il letterale non ha suffisso, ha il primo di questi tipi in cui il suo valore può essere rappresentato: int, uint, lunghe, ulong.
  • Se il letterale è suffisso da U ou, ha il primo di questi tipi in cui il suo valore può essere rappresentato: uint, ulong.
  • Se il letterale è suffisso da L o l, ha il primo di questi tipi in cui il suo valore può essere rappresentato: lungo, molto lungo.
  • Se il letterale è suffisso da UL, Ul, uL, ul, LU, Lu, lU o lu, è di tipo ulong.

0xF0000000 non ha il suffisso, quindi ha il primo tipo che può rappresentarla (int, uint, lunga, ulong)

  • int è 32 bit firmato: 0xF0000000 è solo al di fuori dell'intervallo per valori positivi - Avanti ...
  • uint è a 32 bit senza segno: 0xF0000000 è compreso nell'intervallo - OK.

Quindi 0xF0000000 ha tipo uint.

decimal x = 0xF00000000; 

Qui x è una variabile decimale. Quando assegni ad esso un valore uint, quel valore viene convertito implicitamente in un decimale (quindi si adatta alla variabile decimale).

Problemi correlati