Литмир - Электронная Библиотека
A
A

using System;

using FunWithRecords;

Console.WriteLine("Fun with Records!");

// Использовать инициализацию объекта

Car myCar = new Car

{

    Make = "Honda",

    Model = "Pilot",

    Color = "Blue"

};

Console.WriteLine("My car: ");

DisplayCarStats(myCar);

Console.WriteLine();

// Использовать специальный конструктор

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

Console.WriteLine("Another variable for my car: ");

DisplayCarStats(anotherMyCar);

Console.WriteLine();

// Попытка изменения свойства приводит к ошибке на этапе компиляции.

// myCar.Color = "Red";

Console.ReadLine();

static void DisplayCarStats(Car c)

{

  Console.WriteLine("Car Make: {0}", c.Make);

  Console.WriteLine("Car Model: {0}", c.Model);

  Console.WriteLine("Car Color: {0}", c.Color);

}

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

Чтобы создать тип записи

CarRecord
, добавьте к проекту новый файл по имени
CarRecord.cs
со следующим кодом:

record CarRecord

{

  public string Make { get; init; }

  public string Model { get; init; }

  public string Color { get; init; }

  public CarRecord () {}

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

  {

    Make = make;

    Model = model;

    Color = color;

  }

}

Запустив приведенный далее код из

Program.cs
, вы можете удостовериться в том, что поведение записи
CarRecord
будет таким же, как у класса
Car
со средствами доступа только для инициализации:

Console.WriteLine("/*************** RECORDS *********************/");

// Использовать инициализацию объекта

CarRecord myCarRecord = new CarRecord

{

    Make = "Honda",

    Model = "Pilot",

    Color = "Blue"

};

Console.WriteLine("My car: ");

DisplayCarRecordStats(myCarRecord);

Console.WriteLine();

// Использовать специальный конструктор

CarRecord anotherMyCarRecord = new CarRecord("Honda", "Pilot", "Blue");

Console.WriteLine("Another variable for my car: ");

Console.WriteLine(anotherMyCarRecord.ToString());

Console.WriteLine();

// Попытка изменения свойства приводит к ошибке на этапе компиляции.

// myCarRecord . Color = "Red";

Console.ReadLine();

Хотя мы пока еще не обсуждали эквивалентность (см. следующий раздел) или наследование (см. следующую главу) с типами записей, первое знакомство с записями не создает впечатления, что они обеспечивают большое преимущество. Текущий пример записи

CarRecord
включал весь ожидаемый связующий код. Заметное отличие присутствует в выводе: метод
ToString()
для типов записей более причудлив, как видно в показанном ниже фрагменте вывода:

/*************** RECORDS *********************/

My car:

CarRecord { Make = Honda, Model = Pilot, Color = Blue }

Another variable for my car:

CarRecord { Make = Honda, Model = Pilot, Color = Blue }

Но взгляните на следующее обновленное определение записи

Car
:

record CarRecord(string Make, string Model, string Color);

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

Эквивалентность с типами записей

В примере класса

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

129
{"b":"847442","o":1}