C# properties (свойства) - это почти как getter и setter в Java.
Using Properties (C# Programming Guide)
Свойство в C# - это специальный член класса, который можно использовать как поле, но доступ к значению обрабатывается в специальных функциях.
public class PlantSet
{
private List<Plant> _data;
public List<Plant> Data
{
get
{
if (_data is null)
{
throw new InvalidOperationException("Must be initialized!");
}
return _data;
}
set
{
if (_data is not null)
{
throw new InvalidOperationException("Already initialized!");
}
_data = value;
}
}
}
Можно определить только геттер и тогда запись в свойство будет запрещена.
public class Plant
{
private string Subgenus = "Betula";
private string Species = "Pendula";
public string Name
{
get
{
return $"{Subgenus} {Species}";
}
}
}
Свойства в C# можно использовать аналогично геттерам и сеттерам в других языках программирования.
Свойства - это не переменные и не всегда можно использовать свойство там где можно было использовать поле класса.
Свойства могут иметь следующие модификаторы доступа: public, private, protected, internal, protected internal, private protected.
Если свойство не виртуальное то оно не имеет штрафа за вызов функции для обращении к нему, так как код функции будет встроен в место где было обращение к функции доступа.
get
- геттер, возвращает значение
set
- сеттер, устанавливает значение
init
- разрешена только инициализация значения. Записать в свойство можно будет только в конструкторе или при инициализации объектов.
В примере ниже описан вариант свойства, которое можно только инициализировать и потом читать. Изменение значения - запрещено. В примере используется Expression-bodied для описания тела геттера и сеттера.
public class Plant
{
private string _name;
public string Name
{
get => _name;
init => _name = value;
}
}
Мы можем определить какие свойства с какими get, set, init функциями должны присутствовать в реализованы
public interface IPlant
{
public string Name
{
get;
init;
}
}
// и реализация
public class Plant : IPlant
{
private string _name;
public string Name
{
get => _name;
init => _name = value;
}
}
Как показано в примере ниже, мы можем описать какие функции доступа должны присутсвовать и не предоставлять реализацию. Она будет сченерирована за нас. Очевидно, что такой код можно расширить, при необходимости более сложными алгоритмами.
public class Plant
{
public string Name
{
get;
init;
}
}
// будет аналогично такой реализации
public class Plant
{
private string _name;
public string Name
{
get => _name;
init => _name = value;
}
}
Свойство может быть определено и инициализировано таким образом:
public class Plant
{
// Свойство доступное только для чтения
public string Name { get; } = "Betula pendula";
}