Страница 28 из 502
Если приведение типов приводит к сужающему преобразованию, то часть информации может быть потеряна. Например, в результате приведения типа long к типу int часть информации потеряется, если значение типа long окажется больше диапазона представления чисел для типа int, поскольку старшие разряды этого числового значения отбрасываются. Когда же значение с плавающей точкой приводится к целочисленному, то в результате усечения теряется дробная часть этого числового значения. Так, если присвоить значение 1,23 целочисленной переменной, то в результате в ней останется лишь целая часть исходного числа (1), а дробная его часть (0,23) будет потеряна.
В следующем примере программы демонстрируется ряд преобразований типов, требующих приведения. В этом примере показан также ряд ситуаций, в которых приведение типов становится причиной потери данных.
<b>// Продемонстрировать приведение типов.</b>
<b>using System;</b>
<b>class CastDemo {</b>
<b> static void Main() { </b>
<b> double x, y; </b>
<b> byte b; </b>
<b> int i; </b>
<b> char ch; </b>
<b> uint u; </b>
<b> short s; </b>
<b> long l;</b>
<b> x = 10.0;</b>
<b> y = 3.0;</b>
<b> // Приведение типа double к типу int, дробная часть числа теряется, </b>
<b> i = (int)(x / y) ;</b>
<b> Console.WriteLine("Целочисленный результат деления х / у: " + i) ; </b>
<b> Console.WriteLine();</b>
<b> // Приведение типа int к типу byte без потери данных, </b>
<b> i = 255; </b>
<b> b = (byte)i;</b>
<b> Console.WriteLine("b после присваивания 255: " + b + " -- без потери данных.");</b>
<b> // Приведение типа int к типу byte с потерей данных, </b>
<b> i = 257; </b>
<b> b = (byte)i;</b>
<b> Console.WriteLine("b после присваивания 257: " + b + " — с потерей данных.");</b>
<b> Console.WriteLine();</b>
<b> // Приведение типа uint к типу short без потери данных, </b>
<b> u = 32000; </b>
<b> s = (short) u;</b>
<b> Console.WriteLine("s после присваивания 32000: " + s + " — без потери данных.");</b>
<b> // Приведение типа uint к типу short с потерей данных, </b>
<b> u = 64000; </b>
<b> s = (short)u;</b>
<b> Console.WriteLine("s после присваивания 64000: " + s + " — с потерей данных. ") ;</b>
<b> Console.WriteLine();</b>
<b> // Приведение типа long к типу uint без потери данных.</b>
<b> l = 64000; </b>
<b> u = (uint)l;</b>
<b> Console.WriteLine("и после присваивания 64000: " + u + " -- без потери данных.");</b>
<b> // Приведение типа long к типу uint с потерей данных.</b>
<b> l = -12; </b>
<b> u = (uint)1;</b>
<b> Console.WriteLine("и после присваивания -12: " + u + " — с потерей данных.");</b>
<b> Console.WriteLine();</b>
<b> // Приведение типа int к типу char,</b>
<b> b = 88; // код ASCII символа X</b>
<b> ch = (char) b;</b>
<b> Console.WriteLine("ch после присваивания 88: " + ch);</b>
<b> }</b>
<b>}</b>
Вот какой результат дает выполнение этой программы.
<b>Целочисленный результат деления х / у: 3</b>
<b>b после присваивания 255: 255 -- без потери данных.</b>
<b>b после присваивания 257: 1 — с потерей данных.i</b>
<b>s после присваивания 32000: 32000 -- без потери данных,</b>
<b>s после присваивания 64000: -1536 -- с потерей данных.</b>
<b>u после-присваивания 64000: 64000 — без потери данных,</b>
<b>u после присваивания -12: 4294967284 -- с потерей данных.</b>
<b>ch после присваивания 88: X</b>
Рассмотрим каждую операцию присваивания в представленном выше примере программы по отдельности. Вследствие приведения результата деления х/у к типу int отбрасывается дробная часть числа, а следовательно, теряется часть информации.
Когда переменной b присваивается значение 255, то информация не теряется, поскольку это значение входит в диапазон представления чисел для типа byte. Но когда переменной b присваивается значение 257, то часть информации теряется, поскольку это значение превышает диапазон представления чисел для типа byte. Приведение типов требуется в обоих случаях, поскольку неявное преобразование типа int в тип byte невозможно.