Несмотря на то что в структурах можно было бы создать вспомогательные методы (наподобие Rectangle.ToSquare()), язык C# позволяет строить специальные процедуры преобразования, которые дают типам возможность реагировать на операцию приведения (). Следовательно, если корректно сконфигурировать структуры, тогда для явного преобразования между ними можно будет применять такой синтаксис:

// Преобразовать Rectangle в Square!

Rectangle rect = new Rectangle

{

  Width = 3;

  Height = 10;

}

Square sq = (Square)rect;

<p id="AutBody_Root420">Создание специальных процедур преобразования</p>

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

using System;

namespace CustomConversions

{

  public struct Rectangle

  {

    public int Width {get; set;}

    public int Height {get; set;}

    public Rectangle(int w, int h)

    {

      Width = w;

      Height = h;

    }

    public void Draw()

    {

      for (int i = 0; i < Height; i++)

      {

        for (int j = 0; j < Width; j++)

        {

          Console.Write("*");

        }

        Console.WriteLine();

      }

    }

    public override string ToString()

      => $"[Width = {Width}; Height = {Height}]";

  }

}

using System;

namespace CustomConversions

{

  public struct Square

  {

    public int Length {get; set;}

    public Square(int l) : this()

    {

      Length = l;

    }

  public void Draw()

    {

      for (int i = 0; i < Length; i++)

      {

        for (int j = 0; j < Length; j++)

        {

          Console.Write("*");

        }

        Console.WriteLine();

      }

    }

    public override string ToString() => $"[Length = {Length}]";

    // Rectangle можно явно преобразовывать в Square.

    public static explicit operator Square(Rectangle r)

    {

      Square s = new Square {Length = r.Height};

      return s;

    }

  }

}

Обратите внимание, что в текущей версии типа Square определена явная операция преобразования. Подобно перегрузке операций процедуры преобразования используют ключевое слово operator в сочетании с ключевым словом explicit или implicit и должны быть определены как static. Входным параметром является сущность, из которой выполняется преобразование, а типом операции — сущность, в которую производится преобразование.

В данном случае предположение заключается в том, что квадрат (будучи геометрической фигурой с четырьмя сторонами равной длины) может быть получен из высоты прямоугольника. Таким образом, вот как преобразовать Rectangle в Square:

using System;

using CustomConversions;

Console.WriteLine("***** Fun with Conversions *****\n");

// Создать экземпляр Rectangle.

Rectangle r = new Rectangle(15, 4);

Console.WriteLine(r.ToString());

r.Draw();

Console.WriteLine();

// Преобразовать r в Square на основе высоты Rectangle.

Square s = (Square)r;

Console.WriteLine(s.ToString());

s.Draw();

Console.ReadLine();

Ниже показан вывод:

***** Fun with Conversions *****

[Width = 15; Height = 4]

***************

***************

***************

***************

[Length = 4]

****

****

****

****

Хотя преобразование Rectangle в Square в пределах той же самой области действия может быть не особенно полезным, взгляните на следующий метод, который спроектирован для приема параметров типа Square:

// Этот метод требует параметр типа Square.

static void DrawSquare(Square sq)

{

  Console.WriteLine(sq.ToString());

  sq.Draw();

}

Перейти на страницу:

Похожие книги