Выбрать главу

Кроме методов, задающих преобразования типов, в классе Convert имеются и другие методы, например, задающие преобразования символов Unicode в однобайтную кодировку ASCII, преобразования значений объектов и другие методы. Подробности можно посмотреть в справочной системе.

Проверяемые преобразования

Уже упоминалось о том, что при выполнении явных преобразований могут возникать нежелательные явления, например, потеря точности. Я говорил, что вся ответственность за это ложится на программиста, и легче ему от этого не становится. А какую часть этого бремени может взять на себя язык программирования? Что можно предусмотреть для обнаружения ситуаций, когда такие явления все-таки возникают? В языке C# имеются необходимые для этого средства.

Язык C# позволяет создать проверяемый блок, в котором будет осуществляться проверка результата вычисления арифметических выражений. Если результат вычисления значения источника выходит за диапазон возможных значений целевой переменной, то возникнет исключение (говорят также: "будет выброшено исключение") соответствующего типа. Если предусмотрена обработка исключения, то дальнейшее зависит от обработчика исключения. В лучшем случае, программа сможет продолжить корректное выполнение. В худшем, — она остановится и выдаст информацию об ошибке. Заметьте, не произойдет самого опасного — продолжения работы программы с неверными данными.

Синтаксически проверяемый блок предваряется ключевым словом checked, в теле такого блока арифметические преобразования проверяются на допустимость. Естественно, подобная проверка требует дополнительных временных затрат. Если группа операторов в теле такого блока нам кажется безопасной, то их можно выделить в непроверяемый блок, используя ключевое слово unchecked.

Замечу еще, что и в непроверяемом блоке при работе методов Convert все опасные преобразования проверяются и приводят к выбрасыванию исключений. Приведу пример, демонстрирующий все описанные ситуации:

/// <summary>

/// Демонстрация проверяемых и непроверяемых преобразований.

/// Опасные проверяемые преобразования приводят к исключениям.

/// Опасные непроверяемые преобразования приводят к неверным

/// результатам, что совсем плохо.

/// </summary>

public void CheckUncheckTest()

     x = —25 ^2;

     WhoIsWho ("x", x);

     b= 2 55;

     WhoIsWho("b",b);

     // Проверяемые опасные преобразования.

     // Возникают исключения, перехватываемые catch-блоком,

     checked

     {

         try

         {

             b += 1;

         }

         catch (Exception e)

         {

              Console.WriteLine("Переполнение при вычислении b");

              Console.WriteLine(e);

         }

         try

         {

               b = (byte)x;

          }

          catch (Exception e)

          {

               Console.WriteLine("Переполнение при преобразовании к byte");

               Console.WriteLine(e);

          }

         // непроверяемые опасные преобразования

         unchecked

          {

               try

               {

                   b +=1;

                          WhoIsWho ("b", b);

                   b = (byte)x;

                   WhoIsWho ("b", b);

                   ux= (uint)x;

                   WhoIsWho ("ux", ux);

                   Console.WriteLine("Исключений нет, но результаты не верны!");

               }

               catch (Exception е)

               {

                   Console.WriteLine("Этот текст не должен появляться");

                   Console.WriteLine (е);

                }

               // автоматическая проверка преобразований в Convert

               // исключения возникают, несмотря на unchecked

               try

               }

                    b = Convert.ToByte(х);

               }

               catch (Exception е)

               {

                     Console.WriteLine("Переполнение при преобразовании к byte!");

                     Console.WriteLine(е);

                }

                try

                {

                     ux= Convert.ToUInt32(х);

                }

                catch (Exception e)

                {

                     Console.WriteLine("Потеря знака при преобразовании к uint!");