C# → Приведение типов

Приведем сразу пример приведения типов в C#:

      public struct Currency
      {     // неявное приведение типа
            public static implicit operator float(Currency value)
            {
                return value.Grn + (value.Kop / 100.0f);
            }
            // явное приведение типа
            public static explicit operator Currency(float value)
            {
                checked {
                    uint Grn = (uint)value;
                    ushort Kop = (ushort)((value - Grn) * 100);
                    return new Currency(Grn, Kop); }
            }
        } ... 
      // неявное преобразование
      Currency balance = new Currency(10,50);  // 10 грн. 50 коп.
      float D = balance; // нужно чтобы D было присвоено 10.50
      // явное преобразование
      float money = 45.63f;
      Currency myMoney = (Currency)money;

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

Всегда можно неявно привести производный класс к базовому, а базовый явно к производному. Ссылка на базовый тип может ссылаться как на объекты базового класса, так и на объекты производные от него.

Currency c = new Currency();      
Base cb = new Currency();  // неявное приведение Currency к Base

Если объект не является экземпляром производного класса (или любого класса, являющегося производным от него, преобразования типа не происходит и генерируется исключение.

Base b = new Currency();
Base bs = new Base();
Currency c1 = (Currency)b;
Currency c2 = (Currency)bs;  // неверно, приходится отсекать данные

Упаковка:

Currency c = new Currency(); object b = c; // функц. C будет потеряна

Распаковка:

object c = new Currency();
object b = new object();
Currency c1 = (Currency)c;  // возможно
Currency c2 = (Currency)c;  // не возможно

Приведение типов очень тонкая, местами опасная вещь (Console.WriteLine(Curreny) – не существует перегруженной версии для Currency поэтому, объект будет преобразовано к float или uint (которые мы определили выше) что может вызвать вывод не правильного резульатат).