Шрифт:
Интервал:
Закладка:
// Скрытое поддерживающее поле установлено в 1.
public int NumberOfCars { get; set; } = 1;
// Скрытое поддерживающее поле установлено в новый объект Car.
public Car MyAuto { get; set; } = new Car();
public Garage(){}
public Garage(Car car, int number)
{
MyAuto = car;
NumberOfCars = number;
}
}
Наверняка вы согласитесь с тем, что автоматические свойства — очень полезное средство языка программирования С#, т.к. отдельные свойства в классе можно определять с применением модернизированного синтаксиса. Конечно, если вы создаете свойство, которое помимо получения и установки закрытого поддерживающего поля требует дополнительного кода (такого как логика проверки достоверности, регистрация в журнале событий, взаимодействие с базой данных и т.д.), то его придется определять как "нормальное" свойство .NET Core вручную. Автоматические свойства C# не делают ничего кроме обеспечения простой инкапсуляции для лежащей в основе порции (сгенерированных компилятором) закрытых данных.
Понятие инициализации объектов
На протяжении всей главы можно заметить, что при создании нового объекта конструктор позволяет указывать начальные значения. Вдобавок свойства позволяют безопасным образом получать и устанавливать лежащие в основе данные. При работе со сторонними классами, включая классы из библиотеки базовых классов .NET Core, нередко обнаруживается, что в них отсутствует конструктор, который позволял бы устанавливать абсолютно все порции данных состояния. В итоге программист обычно вынужден выбирать наилучший конструктор из числа возможных и затем присваивать остальные значения с использованием предоставляемого набора свойств.
Обзор синтаксиса инициализации объектов
Для упрощения процесса создания и подготовки объекта в C# предлагается синтаксис инициализации объектов. Такой прием делает возможным создание новой объектной переменной и присваивание значений многочисленным свойствам и/или открытым полям в нескольких строках кода. Синтаксически инициализатор объекта выглядит как список разделенных запятыми значений, помещенный в фигурные скобки ({}). Каждый элемент в списке инициализации отображается на имя открытого поля или открытого свойства инициализируемого объекта.
Чтобы увидеть данный синтаксис в действии, создайте новый проект консольного приложения по имени ObjectInitializers. Ниже показан класс Point, в котором присутствуют автоматические свойства (для синтаксиса инициализации объектов они не обязательны, но помогают получить более лаконичный код):
class Point
{
public int X { get; set; }
public int Y { get; set; }
public Point(int xVal, int yVal)
{
X = xVal;
Y = yVal;
}
public Point() { }
public void DisplayStats()
{
Console.WriteLine("[{0}, {1}]", X, Y);
}
}
А теперь посмотрим, как создавать объекты Point, с применением любого из следующих подходов:
Console.WriteLine("***** Fun with Object Init Syntax *****n");
// Создать объект Point, устанавливая каждое свойство вручную.
Point firstPoint = new Point();
firstPoint.X = 10;
firstPoint.Y = 10;
firstPoint.DisplayStats();
// Или создать объект Point посредством специального конструктора.
Point anotherPoint = new Point(20, 20);
anotherPoint.DisplayStats();
// Или создать объект Point, используя синтаксис инициализации объектов.
Point finalPoint = new Point { X = 30, Y = 30 };
finalPoint.DisplayStats();
Console.ReadLine();
При создании последней переменной Point специальный конструктор не используется (как делается традиционно), а взамен устанавливаются значения открытых свойств X и Y. "За кулисами" вызывается стандартный конструктор типа, за которым следует установка значений указанных свойств. В таком отношении синтаксис инициализации объектов представляет собой просто сокращение синтаксиса для создания переменной класса с применением стандартного конструктора и установки данных состояния свойство за свойством.
На заметку! Важно помнить о том, что процесс инициализации объектов неявно использует методы установки свойств. Если метод установки какого-то свойства помечен как private, тогда этот синтаксис применить не удастся.
Использование средства доступа только для инициализации (нововведение в версии 9.0)
В версии C# 9.0 появилось новое средство доступа только для инициализации. Оно позволяет устанавливать свойство во время инициализации, но после завершения конструирования объекта свойство становится доступным только для чтения. Свойства такого типа называются неизменяемыми. Добавьте к проекту новый файл класса по имени ReadOnlyPointAfterCreation.cs и поместите в него следующий код:
using System;
namespace ObjectInitializers
{
class PointReadOnlyAfterCreation
{
public int X { get; init; }
public int Y { get; init; }
public void DisplayStats()
{
Console.WriteLine("InitOnlySetter: [{0}, {1}]", X, Y);
}
public PointReadOnlyAfterCreation(int xVal, int yVal)
{
X = xVal;
Y = yVal;
}
public PointReadOnlyAfterCreation() { }
}
}
Новый класс тестируется с применением приведенного ниже кода:
// Создать объект точки, допускающий только чтение
// после конструирования
PointReadOnlyAfterCreation firstReadonlyPoint =
new PointReadOnlyAfterCreation(20, 20);
firstReadonlyPoint.DisplayStats();
// Или создать объект точки с использованием синтаксиса только
// для инициализации.
PointReadOnlyAfterCreation secondReadonlyPoint =
new PointReadOnlyAfterCreation { X = 30, Y = 30 };
secondReadonlyPoint.DisplayStats();
Обратите внимание, что в коде для класса Point ничего не изменилось кроме, разумеется, имени класса. Отличие в том, что после создания экземпляра класса модифицировать значения свойств X и Y нельзя. Например, показанный далее код не скомпилируется:
// Следующие две строки не скомпилируются
secondReadonlyPoint.X = 10;
secondReadonlyPoint.Y = 10;
Вызов специальных конструкторов с помощью синтаксиса инициализации
В предшествующих примерах объекты типа Point инициализировались путем неявного вызова стандартного конструктора этого типа:
// Здесь стандартный конструктор вызывается неявно.
Point finalPoint = new Point { X = 30, Y = 30 };
При желании стандартный конструктор допускается вызывать и явно:
// Здесь стандартный конструктор вызывается явно.
Point finalPoint = new Point() { X = 30, Y = 30 };
Имейте в виду, что при конструировании объекта типа с использованием синтаксиса инициализации можно вызывать любой конструктор, определенный в
- QT 4: программирование GUI на С++ - Жасмин Бланшет - Программирование
- C# для профессионалов. Том II - Симон Робинсон - Программирование
- C# 4.0: полное руководство - Герберт Шилдт - Программирование
- Программирование игр и головоломок - Жак Арсак - Программирование
- Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT. Часть 2 - Александр Фролов - Программирование
- Графические интерфейсы пользователя Java - Тимур Сергеевич Машнин - Программирование
- Гибкое управление проектами и продуктами - Борис Вольфсон - Программирование
- Каждому проекту своя методология - Алистэр Коуберн - Программирование
- От «Энигмы» до ChatGPT - Рустам Агамалиев - Программирование / Экономика
- Как почистить сканы книг и сделать книгу - IvanStorogev? KpNemo - Программирование