Преобразование типов в C#

В C# каждой переменной должен быть назначен свой тип. Изменить тип переменной нельзя. Узнать точный тип переменной можно с помощью метода GetType(). Метод GetType() наследуется от типа Object. Так как все типы C# явным или неявным образом наследуются от типа Object, поэтому этот метод доступен для всех остальных типов. Метод GetType() типа Object не виртуальный, его нельзя переопределить в производных типах.

При разработке программ часто нужно преобразовать значение переменной одного типа в значение переменной другого. В C# есть следующие способы преобразования одного типа к другому:

  • Явное преобразование – преобразование одного типа к другому при помощи специального оператора приведения типов. Такое преобразование называется приведением типов.
  • Неявное преобразование – осуществляется автоматически. При этом среда выполнения позволяет преобразовать тип к любому из его базовых типов.
  • Пользовательское преобразование – осуществляется при помощи операторов пользовательского преобразования.
  • Преобразования при помощи специальных классовSystem.Convert, System.BitConverter и др.

Неявное преобразование

Для числовых типов данных в C# выполняется неявное преобразование, если размер типа, для которого выполняется преобразование, меньше или равен размеру типа в который сохраняется значение. Т.е. если при преобразовании типов исключается возможность потери данных.

byte b = 100;
int i = b;

Неявное преобразование типов в примере выше возможно благодаря тому что тип byte меньше int, следовательно любое значение типа byte поместится в переменной типа int.

Обратное преобразование (int в byte) требует явного преобразования, т.к. возможна частичная потеря данных. Следующий код генерирует исключение:

int i = 100;
byte b = i; //error CS0266: Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)

Неявное преобразование переменных ссылочных типов допускается к любому базовому типу, или к любому интерфейсу, который реализует тип переменной или любой базовый тип этой переменной.

string s = string.Empty;
object o = s;

Такое преобразование возможно т.к. тип object является базовым для всех типов в C#. Обратное преобразование требует использования синтаксиса приведения типов.


Явное преобразование типов (приведение типов)

Для числовых типов, если есть вероятность потери данных при преобразовании среда выполнения CLR требует явного преобразования типов. При этом используется оператор явного приведения типов – скобки. Явное преобразование типов называется приведением типов. В результате такого преобразования возможна потеря данных.

В следующем коде происходит потеря данных при приведении типов:

short s = 1000;
byte b = ( byte )s;

Console.WriteLine( b );
// Вывод: 232

За счет того, что переменной s присвоено значение большее чем может поместиться в переменную типа byte, в результате приведения типов происходит переполнение и в переменной b оказывается значение 232, а не 1000.

Эта ситуация показана на рисунке ниже:

Потеря данных в результате приведения типов
Потеря данных в результате приведения типов

В результате приведения были отброшены старшие 8 бит информации. В результирующую переменную b были записаны только младшие 8 бит, отсюда и неожиданный результат преобразования.


Приведение ссылочных типов

Приведение ссылочных типов возможно, если объект был ранее преобразован к базовому типу. Пример приведения ссылочного типа:

using System;

namespace Program_ {
    class A { } // Пустой класс A
    
    class Program {
        static void Main( string[] args ) {
            object o = new A();

            // Преобразование возможно так как переменная o
            // ссылается на объект типа A
            A a = ( A ) o;
            Console.ReadKey();
        }
    }
}

Следующий пример вызовет исключение времени выполнения:

object o = new object();

// Преобразование не возможно так как переменная o
// не является объектом типа A
A a = ( A ) o;

Безопасное приведение ссылочных типов с помощью операторов is и as

Иногда нужно проверить тип объекта перед приведением к другому типу что бы не вызвать исключение. Оператор is выполняет проверку типа объекта и возвращает true, если объект соответствует заданному типу и false если не соответствует. Если ссылка пуста, т.е. ее значение равно null, оператор возвращает false:

object o = new object();
A a1 = new A();
A a2 = null;

Console.WriteLine( a1 is A );
Console.WriteLine( a2 is object );
Console.WriteLine( o is A );

После проверки объекта на соответствие типу можно выполнить приведение объекта к нужному типу:

object o = new A();

if ( o is A ) {    // проверка объекта на принадлежность к типу
    A a = ( A ) o; // приведение объекта o к типу A
}

При помощи оператора as можно выполнить приведение к типу немного быстрее. Оператор as проверяет можно ли привести объект к заданному типу или нет. Если преобразование возможно, оператор возвращает приведенный объект, если нет – null.

object o = new A();

A a = o as A;      // попытка приведения к типу A

if ( A == null ) { 
   // выполнить какие-либо действия если приведение невозможно
}
else {
   // ... если удалось привести объект к нужному типу
}
avatar
5000
  Подписаться  
Уведомление о