public string Color { get; init; }

    public Car(string make, string model, string color)

    {

      Make = make;

      Model = model;

      Color = color;

    }

  }

}

// MiniVan.cs

namespace RecordInheritance

{

    //MiniVan record type

    public sealed record MiniVan : Car

    {

        public int Seating { get; init; }

         public MiniVan(string make, string model, string color, int seating)

           : base(make, model, color)

        {

            Seating = seating;

        }

    }

}

Обратите внимание, что между примерами использования типов записей и предшествующими примерами применения классов нет большой разницы. Модификатор доступа protected для свойств и методов ведет себя аналогично, а модификатор доступа sealed для типа записи запрещает другим типам записей быть производными от запечатанных типов записей. Вы также обнаружите работу с унаследованными типами записей в оставшихся разделах главы. Причина в том, что типы записей — это всего лишь особый вид неизменяемого класса (как объяснялось в главе 5). Вдобавок типы записей включают неявные приведения к своим базовым классам, что демонстрируется в коде ниже:

using System;

using RecordInheritance;

Console.WriteLine("Record type inheritance!");

Car c = new Car("Honda","Pilot","Blue");

MiniVan m = new MiniVan("Honda", "Pilot", "Blue",10);

Console.WriteLine($"Checking MiniVan is-a Car:{m is Car}");

                 // Проверка, является ли MiniVan типом Car

Как и можно было ожидать, проверка того, что m является Car, возвращает true, как видно в следующем выводе:

Record type inheritance!

Checking minvan is-a car:True

Важно отметить, что хотя типы записей представляют собой специализированные классы, вы не можете организовывать перекрестное наследование между классами и записями. Другими словами, классы нельзя наследовать от типов записей, а типы записей не допускается наследовать от классов. Взгляните на приведенный далее код; последние два примера не скомпилируются:

namespace RecordInheritance

{

  public class TestClass { }

  public record TestRecord { }

  // Классы не могут быть унаследованы от записей

  // public class Test2 : TestRecord { }

  // Записи не могут быть унаследованы от классов

  // public record Test2 : TestClass {  }

}

Наследование также работает с позиционными типами записей. Создайте в своем проекте новый файл по имени PositionalRecordTypes.cs и поместите в него следующий код:

namespace RecordInheritance

{

  public record PositionalCar (string Make, string Model, string Color);

  public record PositionalMiniVan (string Make, string Model, string Color)

    : PositionalCar(Make, Model, Color);

}

Добавьте к операторам верхнего уровня показанный ниже код, с помощью которого можно подтвердить то, что вам уже известно: позиционные типы записей работают точно так же, как типы записей.

PositionalCar pc = new PositionalCar("Honda", "Pilot", "Blue");

PositionalMiniVan pm = new PositionalMiniVan("Honda", "Pilot", "Blue", 10);

Console.WriteLine($"Checking PositionalMiniVan is-a PositionalCar:

  {pm is PositionalCar}");

<p id="AutBody_Root270">Эквивалентность с унаследованными типами записей</p>

Вспомните из главы 5, что для определения эквивалентности типы записей используют семантику значений. Еще одна деталь относительно типов записей связана с тем, что тип записи является частью соображения, касающегося эквивалентности. Скажем, взгляните на следующие тривиальные примеры:

public record MotorCycle(string Make, string Model);

public record Scooter(string Make, string Model) : MotorCycle(Make,Model);

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

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