Полные свойства с резервными полями
Добавляйте логику в методы получения и установки значений.
«Полные свойства с резервными полями» — бесплатный урок C# Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.
За пределами автоматически реализуемых свойств
Когда Вам нужна логика внутри get или set, напишите полное свойство с явным резервным полем. Поле хранит данные, а методы доступа управляют доступом к ним.
using System;
class Temperature
{
private double _celsius;
public double Celsius
{
get { return _celsius; }
set { _celsius = value; }
}
}
class Program
{
static void Main()
{
var t = new Temperature();
t.Celsius = 21.5;
Console.WriteLine(t.Celsius);
}
}Соглашение об именовании резервного поля
По соглашению резервное поле является private и получает имя с начальным символом подчёркивания, например _name. Открытое свойство предоставляет доступ к нему.
using System;
class Person
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
class Program
{
static void Main()
{
var p = new Person();
p.Name = "Grace";
Console.WriteLine(p.Name);
}
}Ключевое слово value
Внутри метода доступа set неявный параметр value содержит присваиваемое значение. Вы сами решаете, что с ним делать.
using System;
class Box
{
private int _size;
public int Size
{
get { return _size; }
set { _size = value * 2; }
}
}
class Program
{
static void Main()
{
var box = new Box();
box.Size = 10;
Console.WriteLine("Stored size: " + box.Size);
}
}Проверка в методе записи
Распространённое применение полного свойства — проверка входных данных перед сохранением: если значение недопустимо, создаётся исключение.
using System;
class Account
{
private decimal _balance;
public decimal Balance
{
get { return _balance; }
set
{
if (value < 0)
throw new ArgumentException("Balance cannot be negative");
_balance = value;
}
}
}
class Program
{
static void Main()
{
var a = new Account();
a.Balance = 500m;
Console.WriteLine("Balance: " + a.Balance);
}
}Вычисляемые свойства только для чтения
Свойство только с методом доступа get может вычислять своё значение на основе других полей. Резервное поле не требуется, поскольку ничего не хранится.
using System;
class Rectangle
{
private double _width;
private double _height;
public Rectangle(double w, double h)
{
_width = w;
_height = h;
}
public double Area
{
get { return _width * _height; }
}
}
class Program
{
static void Main()
{
var r = new Rectangle(4, 5);
Console.WriteLine("Area: " + r.Area);
}
}Побочные эффекты в методах записи
Метод записи может не только сохранять значение: он может нормализовать входные данные, обновлять связанное состояние или записывать изменения в журнал.
using System;
class User
{
private string _email;
public string Email
{
get { return _email; }
set { _email = value.Trim().ToLower(); }
}
}
class Program
{
static void Main()
{
var u = new User();
u.Email = " Hello@Example.COM ";
Console.WriteLine("Normalized: " + u.Email);
}
}Отложенное вычисление в методе чтения
Метод чтения может при первом запросе сохранить дорогостоящий результат в резервном поле.
using System;
class Report
{
private string _cached;
public string Content
{
get
{
if (_cached == null)
_cached = "Generated at runtime";
return _cached;
}
}
}
class Program
{
static void Main()
{
var r = new Report();
Console.WriteLine(r.Content);
Console.WriteLine(r.Content);
}
}Защита от некорректного состояния
Объедините резервное поле с логикой, чтобы объект всегда оставался корректным. В этом примере метод записи ограничивает значение заданным диапазоном.
using System;
class Volume
{
private int _level;
public int Level
{
get { return _level; }
set
{
if (value < 0) _level = 0;
else if (value > 100) _level = 100;
else _level = value;
}
}
}
class Program
{
static void Main()
{
var v = new Volume();
v.Level = 150;
Console.WriteLine("Clamped: " + v.Level);
}
}Сочетание хранимых и вычисляемых свойств
В классе часто сочетаются хранимые свойства с резервными полями и вычисляемые свойства только для чтения, производные от них.
using System;
class Employee
{
private string _first;
private string _last;
public string First { get { return _first; } set { _first = value; } }
public string Last { get { return _last; } set { _last = value; } }
public string FullName { get { return _first + " " + _last; } }
}
class Program
{
static void Main()
{
var e = new Employee { First = "Marie", Last = "Curie" };
Console.WriteLine(e.FullName);
}
}Уведомление об изменениях
Методы записи естественным образом подходят для уведомления об изменении данных; этот приём широко используется в платформах пользовательского интерфейса.
using System;
class Model
{
private int _count;
public int Count
{
get { return _count; }
set
{
if (_count != value)
{
_count = value;
Console.WriteLine("Count changed to " + _count);
}
}
}
}
class Program
{
static void Main()
{
var m = new Model();
m.Count = 1;
m.Count = 1;
m.Count = 2;
}
}Объединение всего изученного
Полные свойства позволяют классу поддерживать инварианты и предоставлять производные данные через единый понятный интерфейс, похожий на доступ к полю.
using System;
class Thermostat
{
private double _target;
public double Target
{
get { return _target; }
set { _target = value < 10 ? 10 : value; }
}
public string Status { get { return _target >= 22 ? "Warm" : "Cool"; } }
}
class Program
{
static void Main()
{
var th = new Thermostat();
th.Target = 5;
Console.WriteLine(th.Target + " -> " + th.Status);
th.Target = 24;
Console.WriteLine(th.Target + " -> " + th.Status);
}
}Быстрая проверка
Проверьте, насколько хорошо Вы поняли полные свойства.
Итоги
Полное свойство объединяет закрытое резервное поле с явными методами доступа get/set, благодаря чему можно добавить проверку, нормализацию, кэширование или уведомления об изменениях. Вычисляемые свойства только для чтения имеют лишь метод чтения и не используют резервное поле. Ключевое слово value содержит присваиваемое значение внутри метода записи.
using System;
class Demo
{
private int _n;
public int N
{
get { return _n; }
set { _n = value < 0 ? 0 : value; }
}
public int Doubled { get { return _n * 2; } }
}
class Program
{
static void Main()
{
var d = new Demo();
d.N = -5;
Console.WriteLine(d.N + ", " + d.Doubled);
}
}Часто задаваемые вопросы
Урок «Полные свойства с резервными полями» бесплатный?
Да — полный текст урока «Полные свойства с резервными полями» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.
Чему я научусь в уроке «Полные свойства с резервными полями»?
Добавляйте логику в методы получения и установки значений. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C# Academy?
Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Полные свойства с резервными полями»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C# Academy?
Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Автоматически реализуемые свойства
- Полные свойства с резервными полями
- Члены с телом-выражением
- Индексаторы