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 *********************/");
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})
// Использовать инициализацию объекта
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 создавались с одними и теми же данными. В приведенной далее проверке может показаться, что следующие два экземпляра класса эквивалентны: