Книга: ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание

Определение подпрограмм неявного преобразования

Определение подпрограмм неявного преобразования

До этого момента мы с вами создавали пользовательские операции явного преобразования. Но что можно сказать о следующем неявном преобразовании?

static void Main(string[] args) {
 …
 // Попытка выполнить неявное преобразование?
 Square s3;
 s3.Length = 83;
 Rectangle rect2 = s3;
}

Как вы можете догадаться сами, этот программный код скомпилирован не будет, поскольку в нем не предлагается никакой подпрограммы неявного преобразования для типа Rectangle. Тут нас подстерегает "ловушка": в одном и том же типе нельзя определять явные и неявные функции преобразования, не отличающиеся по типу возвращаемого значения или по набору параметров. Может показаться, что это правило является слишком ограничивающим, но не следует забывать о том, что даже если тип определяет подпрограмму неявного преобразования, вызывающая сторона "имеет право" использовать синтаксис явного преобразования!

Запутались? Чтобы прояснить ситуацию, добавим в структуру Rectangle подпрограмму неявного преобразования, используя ключевое слово C# implicit (в следующем программном коде предполагается, что ширина результирующего Rectangle получается с помощью умножения стороны Square на 2).

public struct Rесtangle {
 …
 public static implicit operator Rectangle(Square s) {
  Rectangle r;
  r.Height = s.Length;
  // Ширина нового прямоугольника равна
  // удвоенной длине стороны квадрата.
  r.Width = s.Length * 2;
 }
}

С такими изменениями вы получаете возможность преобразовывать указанные типы так.

static void Main(string[] args) {
 …
 // Неявное преобразование: все OK!
 Square s3;
 s3.Length = 83;
 Rectangle rect2 = s3;
 Console.WriteLine("rect2 = {0}", rect2);
 DrawSquare(s3);
 // Синтаксис явного преобразования: тоже OK!
 Square s4;
 S4.Length = 3;
 Rectangle rect3 = (Rectangle)s4;
 Console.WriteLine("rect3 = {0}", rect3);
 …
}

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

public struct Square {
 …
 // Можно вызывать как Square sq2 = (Square)90;
 // или как Square sq2 = 90;
 public static implicit operator Square(int sideLength) {
  Square newSq;
  newSq.Length = sideLength;
  return newSq;
  // Должно вызываться как int side = (Square)mySquare;
  public static explicit operator int(Square s) { return s.Length; }
 }
}

Оглавление книги


Генерация: 1.225. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз