2015-11-27 18 views
15

Rozważmy następujący kod:W jaki sposób C# wie, jaki jest typ literału?

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

dlaczego C# drukuje System.UInt32 dla pierwszego i System.Double za drugim?

Czy to dlatego, że domyślnie kompilator podaje literał jako typ var?

+53

Nie ma typu "var". –

Odpowiedz

57

W tej linii:

double i = 0xF0000000; 

dosłowne jest typu uint, ale to jest niejawnie konwertowane na double. Podczas rozmowy telefonicznej i.GetType() które zawsze druku System.Double, ponieważ zmienna jest typu double na ... tylko rodzaj wartości może pomieścić jest double.

Zauważ, że ta konwersja do double oznacza, że ​​można stracić precyzji, jeśli zaczynasz z long lub ulong. Na przykład:

using System; 

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

nadrukami

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

Uwaga jak ostatnie kilka cyfr są tracone w double, ponieważ niejawna konwersja z long do double może stracić precyzji. (Obie mają 64 bity dostępne, ale tylko w double niektóre z tych bitów są stosowane dla mantysy).

To nie jest problem dla int lub uint literałów, ale warto mieć świadomość, że nawrócenie się dzieje.

12

Zgodnie z Integer Literals (C#) typ liczby całkowitej jest zależny od wartości i jej przyrostka.

  • Jeżeli dosłownym ma sufiks, ma pierwszy z tych typów, w którym jego wartość może być reprezentowane: INT unit, długości, Ulong.
  • Jeśli literał ma przyrostek U lub u, ma on pierwszy z tych typów, w którym może być reprezentowana jego wartość: uint, ulong.
  • Jeśli literał ma przyrostek L lub l, ma on pierwszy z tych typów, w którym może być reprezentowana jego wartość: długa, ulong.
  • Jeśli literał ma sufiks UL, Ul, uL, ul, LU, Lu, lU lub lu, jest on typu ulong.

0xF0000000 ma sufiks, a więc ma pierwszego typu, które może reprezentować (int unit, długości Ulong)

  • int jest 32-bitową: 0xF0000000 tylko poza zakresem dla wartości dodatnich - Dalej ...
  • uint jest 32-bitowym bez znaku: 0xF0000000 znajduje się w zasięgu - OK.

Tak więc 0xF0000000 ma typ Uint.

decimal x = 0xF00000000; 

Tutaj x jest zmienną dziesiętną. Po przypisaniu do niego wartości uint, wartość ta jest niejawnie przekształcana na wartość dziesiętną (więc będzie pasować do zmiennej dziesiętnej).

Powiązane problemy