Rzutowanie z liczby na liczbę w C#
Niejawne rzutowanie liczb
W metodzie Main wpisz poniższe instrukcje:
double b = a; // liczbę typu int można zapisać w zmiennej typu double
WriteLine(b);
Nie można natomiast niejawnie rzutować liczby typu double na typ int, ponieważ jest to operacja niebezpieczna, która może doprowadzić do utraty danych.
W metodzie Main dopisz poniższe instrukcje:
int d = c; // kompilator zgłosi błąd w tym wierszu
WriteLine(d);
W Visual Studio 2017 naciśnij klawisze Ctrl+W, E, aby otworzyć okno Lista błędów. Powinno ono wyglądać tak jak na poniższym rysunku:
W Visual Studio Code zajrzyj do okienka PROBLEMS albo wprowadź polecenie dotnet run. W efekcie otrzymasz taki komunikat:
/usr/local/share/dotnet/dotnet compile-csc
@/Users/markjprice/Code/Chapter03/Ch03_CastingConverting/obj/
Debug/netcoreapp1.1/dotnet-compile.rsp returned Exit Code 1
/Users/markjprice/Code/Chapter03/Ch03_CastingConverting/Program.cs(14
,21): error CS0266: Cannot implicitly convert type 'double' to 'int'.
An explicit conversion exists (are you missing a cast?)
Compilation failed.
0 Warning(s)
1 Error(s)
Time elapsed 00:00:01.0461813
Jawne rzutowanie liczb
Rzutowanie zmiennych typu double na typ int trzeba wykonać jawnie. W tym celu używa się nawiasów okrągłych, między którymi wpisujemy nazwę typu, na który chcemy dokonać rzutowania. Takie nawiasy okrągłe nazywane są operatorem rzutowania. Wykonując tę operację, musisz mieć
świadomość, że część ułamkowa liczby zostanie odcięta bez żadnego ostrzeżenia.
Zmień teraz instrukcję przypisania do zmiennej d, tak jak w poniższym przykładzie:
int d = (int)c;
WriteLine(d); // w zmiennej d zabraknie ułamka .8
Uruchom aplikację, a zobaczysz, że wypisze ona poniższe wartości:
9
Podobną operację trzeba wykonać podczas przenoszenia liczb z większych typów całkowitych do mniejszych typów całkowitych. W takiej sytuacji również może dojść do utraty danych, ponieważ każda wartość, która nie zmieści się w mniejszym typie, zostanie zmieniona na -1!
Wprowadź do programu poniższy kod:
int f = (int)e;
WriteLine($"e ma wartość {e}, a f ma wartość {f}");
e = long.MaxValue;
f = (int)e;
WriteLine($"e ma wartość {e}, a f ma wartość {f}");
Uruchom aplikację, a zobaczysz taki wynik jej pracy:
e ma wartość 10, a f ma wartość 10
e ma wartość 9223372036854775807, a f ma wartość -1
Używanie typu Convert
Jako alternatywę dla operatora rzutowania można wykorzystać typ System.Convert. Na samym początku pliku Program.cs dopisz taki wiersz kodu:
using static System.Convert;
Teraz dopisz poniższe instrukcje do metody Main:
int h = ToInt32(g);
WriteLine($"g ma wartość {g}, a h ma wartość {h}");
Po uruchomieniu aplikacji konsoli zobaczysz taki wynik:
g ma wartość 9,8, a h ma wartość 10
Jedna z ważnych różnic między rzutowaniem a konwersją polega na tym, że rzutowanie obcina część ułamkową, a konwersja powoduje zaokrąglenie wartości wyjściowej (w tym przypadku do 10).
Typ System.Convert może wykonywać konwersje między dowolnymi typami liczbowymi języka C# oraz wartościami typów logicznych, ciągów znaków, daty i czasu.