Создание пользовательских подпрограмм преобразования

Создание пользовательских подпрограмм преобразования

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

public struct Rectangle {

 // Открыты для простоты,

 // но ничто не мешает инкапсулировать их в виде свойств.

 public int Width, Height;

 public void Draw() { Console.WriteLine("Отображение прямоугольника."); }

 public override string ToString() {

  return string.Format("[Ширина = {0}; Высота = {1}]", Width, Height);

 }

}

public struct Square {

 public int Length;

 public void Draw() { Console.WriteLine("Отображение квадрата."); }

 public override string ToString() { return string.Format("[Сторона = {0}]", Length); }

 // Rectangle (прямоугольник) можно явно преобразовать

 // в Square (квадрат).

 public static explicit operator Square(Rectangle r) {

  Square s;

  s.Length = r.Width;

  return s;

 }

}

Обратите внимание на то, что на этот раз для типа Reсtangle определяется операция явного преобразования. Как и при перегрузке встроенных операций, в C# для подпрограмм преобразования используется ключевое слово operator (в совокупности с ключевым словом explicit или implicit) и эти подпрограммы должны определяться, как статические. Входным параметром является объект, который вы хотите преобразовать, а возвращаемое значение – это объект, в который поступающий объект превращается.

public static explicit operator Square(Rectangle r) {…}

Здесь предполагается, что квадрат (который является геометрической фигурой с равными сторонами) можно получить на основе ширины прямоугольника. Поэтому вы можете превратить Rectangle (прямоугольник) в Square (квадрат) так.

static void Main(string args) {

 Console.WriteLine("***** Забавы с преобразованиями ***** ");

 // Создание прямоугольника 10 х 5.

 Rectangle rect;

 reсt.Width = 10;

 rect.Height = 5;

 Console.WriteLine("rect = {0}", rect);

 // Преобразование прямоугольника в квадрат 10 х 10.

 Square sq = (Square)rect;

 Console.WriteLine("sq = {0}", sq);

 Console.ReadLine();

}

Наверное, от превращения прямоугольников в квадраты в рамках одного контекста не слишком много пользы, но предположим, что у нас есть функция, которая предполагает использование типов Square.

// Этот метод требует использования типа Square.

private static void DrawSquare(Square sq) {

 sq.Draw();

}

Используя нашу операцию явного преобразования, мы можем передавать этой функции типы Square.

static void Main(string[] args) {

 …

 // Преобразование Rectangle в Square для вызова метода.

 DrawSquare((Square)rect);

}