class Car
{
// Автоматические свойства! Нет нужды определять поддерживающие поля.
public string PetName { get; set; }
public int Speed { get; set; }
public string Color { get; set; }
}
}
На заметку! Среды Visual Studio и Visual Studio Code предоставляют фрагмент кода prop. Если вы наберете слово prop внутри определения класса и нажмете клавишу <ТаЬ>, то IDE-среда сгенерирует начальный код для нового автоматического свойства. Затем с помощью клавиши <ТаЬ> можно циклически проходить по всем частям определения и заполнять необходимые детали. Испытайте описанный прием.
При определении автоматического свойства вы просто указываете модификатор доступа, лежащий в основе тип данных, имя свойства и пустые области get/set. Во время компиляции тип будет оснащен автоматически сгенерированным поддерживающим полем и подходящей реализацией логики get/set.
На заметку! Имя автоматически сгенерированного закрытого поддерживающего поля будет невидимым для вашей кодовой базы С#. Просмотреть его можно только с помощью инструмента вроде ildasm.exe.
Начиная с версии C# 6, разрешено определять "автоматическое свойство только для чтения", опуская область set. Автоматические свойства только для чтения можно устанавливать только в конструкторе. Тем не менее, определять свойство, предназначенное только для записи, нельзя. Вот пример:
// Свойство только для чтения? Допустимо!
public int MyReadOnlyProp { get; }
// Свойство только для записи? Ошибка!
public int MyWriteOnlyProp { set; }
Взаимодействие с автоматическими свойствами
Поскольку компилятор будет определять закрытые поддерживающие поля на этапе компиляции (и учитывая, что эти поля в коде C# непосредственно не доступны), в классе, который имеет автоматические свойства, для установки и чтения лежащих в их основе значений всегда должен применяться синтаксис свойств. Указанный факт важно отметить, т.к. многие программисты напрямую используют закрытые поля внутри определения класса, что в данном случае невозможно. Например, если бы класс Car содержал метод DisplayStats, то в его реализации пришлось бы применять имена свойств:
class Car
{
// Автоматические свойства!
public string PetName { get; set; }
public int Speed { get; set; }
public string Color { get; set; }
public void DisplayStats
{
Console.WriteLine("Car Name: {0}", PetName);
Console.WriteLine("Speed: {0}", Speed);
Console.WriteLine("Color: {0}", Color);
}
}
При использовании экземпляра класса, определенного с автоматическими свойствами, присваивать и получать значения можно с помощью вполне ожидаемого синтаксиса свойств:
using System;
using AutoProps;
Console.WriteLine("***** Fun with Automatic Properties *****\n");
Car c = new Car;
c.PetName = "Frank";
c.Speed = 55;
c.Color = "Red";
Console.WriteLine("Your car is named {0}? That's odd...",
c.PetName);
c.DisplayStats;
Console.ReadLine;
Автоматические свойства и стандартные значения
Когда автоматические свойства применяются для инкапсуляции числовых и булевских данных, их можно использовать прямо внутри кодовой базы, т.к. скрытым поддерживающим полям будут присваиваться безопасные стандартные значения (false для булевских и 0 для числовых данных). Но имейте в виду, что когда синтаксис автоматического свойства применяется для упаковки переменной другого класса, то скрытое поле ссылочного типа также будет установлено в стандартное значение null (и это может привести к проблеме, если не проявить должную осторожность).
Добавьте к текущему проекту новый файл класса по имени Garage (представляющий гараж), в котором используются два автоматических свойства (разумеется, реальный класс гаража может поддерживать коллекцию объектов Car; однако в данный момент проигнорируем такую деталь):
namespace AutoProps
{
class Garage
{
// Скрытое поддерживающее поле int установлено в О!
public int NumberOfCars { get; set; }