← Все вопросы

Зачем нужны свойства get/set в C#, если есть обычные поля?

Задан 18 месяцев назад1.1к просмотров2 ответа
11

Не понимаю смысла свойств. Зачем писать { get; set; }, если можно просто сделать public-поле? В чём разница и что такое автосвойства?

public string Name;            // поле
public string Name2 { get; set; } // свойство — в чём профит?

2 ответа

18
✓ Принятый ответ — помог автору

Свойство выглядит как поле, но на самом деле это пара методов (get и set), скрытая за удобным синтаксисом. Главный профит — контроль доступа и валидация без изменения внешнего кода.

Сравните. Голое поле ничего не контролирует:

public int Age; // можно присвоить -100, никто не помешает

Свойство с логикой:

class Person
{
    private int age;
    public int Age
    {
        get => age;
        set
        {
            if (value < 0)
                throw new ArgumentException("Возраст не может быть отрицательным");
            age = value;
        }
    }
}

var p = new Person();
p.Age = 25;   // ок
// p.Age = -5; // бросит исключение

Автосвойство — это сокращение, когда никакой особой логики пока не нужно. Компилятор сам создаёт скрытое поле:

public string Name { get; set; }        // чтение и запись
public int Id { get; private set; }      // менять только внутри класса
public string Country { get; } = "RU";   // только чтение, задаётся в конструкторе

Почему свойства, а не публичные поля: можно ограничить запись (private set), сделать только чтение, добавить валидацию или логирование позже — и при этом не сломать код, который уже использует obj.Name. С полем такой переход потребовал бы менять все обращения. Поэтому в C# принято: наружу — свойства, внутри — приватные поля.

7

Ещё пара полезных форм свойств.

Вычисляемое свойство только с get (хранилища нет, считается на лету):

class Rect
{
    public double W { get; set; }
    public double H { get; set; }
    public double Area => W * H; // expression-bodied, только чтение
}

И init-свойства (C# 9) — можно задать только при создании объекта, потом неизменно:

class Point
{
    public int X { get; init; }
    public int Y { get; init; }
}

var p = new Point { X = 1, Y = 2 };
// p.X = 5; // ОШИБКА — после создания менять нельзя

Это удобно для неизменяемых (immutable) объектов.

Ваш ответ

Войдите, чтобы ответить на вопрос.
Поддержать проект