Конструкции get и set в C#

Всем доброго времени суток. На связи Алексей Гулынин. В прошлой статье вы узнали, что такое спецификаторы доступа в C#. В данной статье я бы хотел поговорить о том, что такое свойство в C#, что такое конструкции get и set в С#, для чего они нужны и как их применять. Обращение к полю объекта напрямую является плохой практикой, так как это нарушает инкапсуляцию. Обычно доступ к закрытому полю объекта оборачивают в виде двух открытых методов, в которых можно заложить некую проверку, перед тем как присвоить полю значение. Давайте на простом примере покажу это. Создадим класс Sqrt с одним закрытым полем и двумя открытыми методами, которые осуществляют доступ к этому полю. Будем реализовать задачу вычисления квадратного корня из некоего числа. Также осуществим проверку, чтобы передаваемое число было неотрицательным:
Давайте теперь создадим метод, который будет возвращать корень квадратный из числа:
Давайте теперь в методе Main проверим всё ли у нас нормально:
Пример очень надуманный, написано много лишнего.
В качестве домашнего задания попробуйте сократить число строк кода и сделать его более понятным.
Как мы видим у нас есть два открытых метода. Вместо этих двух методов (в данном случае getParam() и setParam()) можно использовать одно свойство. Вот здесь-то как раз и используются get и set :
Сразу хочу отметить, что свойство ничего не хранит . Все значения объекта хранят поля. Свойство — это лишь некая обертка для поля. Оно нужно, чтобы не писать два открытых метода. В данном случае метод set получает значение (зарезервированное слово value ), а get — возвращает. При работе со свойствами не нужно забывать, что вы работаете с методами, а не с полями. Давайте теперь перепишем код в методе Main:
Весь код можно посмотреть под хайдом.
В данной статье вы узнали, что такое свойство в C#, что такое get и set в C#, и как их использовать при работе с объектами.
На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.
Get set c что это
Кроме обычных методов в языке C# предусмотрены специальные методы доступа, которые называют свойства . Они обеспечивают простой доступ к полям классов и структур, узнать их значение или выполнить их установку.
Определение свойств
Стандартное описание свойства имеет следующий синтаксис:
Вначале определения свойства могут идти различные модификаторы, в частности, модификаторы доступа. Затем указывается тип свойства, после которого идет название свойства. Полное определение свойства содержит два блока: get и set .
В блоке get выполняются действия по получению значения свойства. В этом блоке с помощью оператора return возвращаем некоторое значение.
В блоке set устанавливается значение свойства. В этом блоке с помощью параметра value мы можем получить значение, которое передано свойству.
Блоки get и set еще называются акссесорами или методами доступа (к значению свойства), а также геттером и сеттером.
Здесь в классе Person определено приватное поле name , которая хранит имя пользователя, и есть общедоступное свойство Name . Хотя они имеют практически одинаковое название за исключением регистра, но это не более чем стиль, названия у них могут быть произвольные и не обязательно должны совпадать.
Через это свойство мы можем управлять доступом к переменной name . В свойстве в блоке get возвращаем значение поля:
А в блоке set устанавливаем значение переменной name. Параметр value представляет передаваемое значение, которое передается переменной name.
В программе мы можем обращаться к этому свойству, как к обычному полю. Если мы ему присваиваем какое-нибудь значение, то срабатывает блок set , а передаваемое значение передается в параметр value :
Если мы получаем значение свойства, то срабатывает блок get , который по сути возвращает значение переменной name:
То есть по сути свойство Name ничего не хранит, оно выступает в роли посредника между внешним кодом и переменной name.
Возможно, может возникнуть вопрос, зачем нужны свойства, если мы можем в данной ситуации обходиться обычными полями класса? Но свойства позволяют вложить дополнительную логику, которая может быть необходима при установке или получении значения. Например, нам надо установить проверку по возрасту:
В данном случае переменная age хранит возраст пользователя. Напрямую мы не можем обратиться к этой переменной — только через свойство Age. Причем в блоке set мы устанавливаем значение, если оно соответствует некоторому разумному диапазону. Поэтому при передаче свойству Age значения, которое не входит в этот диапазон, значение переменной не будет изменяться:
Таким образом, свойство позволяет опосредовать и контролировать доступ к данным объекта.
Свойства только для чтения и записи
Блоки set и get не обязательно одновременно должны присутствовать в свойстве. Если свойство определяет только блок get , то такое свойство доступно только для чтения — мы можем получить его значение, но не установить.
И, наоборот, если свойство имеет только блок set , тогда это свойство доступно только для записи — можно только установить значение, но нельзя получить:
Здесь свойство Name доступно только для чтения, поскольку оно имеет только блок get :
Мы можем получить его значение, но НЕ можем установить:
А свойство Age, наоборот, доступно только для записи, поскольку оно имеет только блок set :
Можно установить его значение, но нельзя получить:
Вычисляемые свойства
Свойства необязательно связаны с определенной переменной. Они могут вычисляться на основе различных выражений
В данном случае класс Person имеет свойство Name, которое доступно только для чтения и которое возвращает общее значение на основе значений переменных firstName и lastName.
Модификаторы доступа
Мы можем применять модификаторы доступа не только ко всему свойству, но и к отдельным блокам get и set:
Теперь закрытый блок set мы сможем использовать только в данном классе — в его методах, свойствах, конструкторе, но никак не в другом классе:
При использовании модификаторов в свойствах следует учитывать ряд ограничений:
Модификатор для блока set или get можно установить, если свойство имеет оба блока (и set, и get)
Только один блок set или get может иметь модификатор доступа, но не оба сразу
Модификатор доступа блока set или get должен быть более ограничивающим, чем модификатор доступа свойства. Например, если свойство имеет модификатор public, то блок set/get может иметь только модификаторы protected internal, internal, protected, private protected и private
Автоматические свойства
Свойства управляют доступом к полям класса. Однако что, если у нас с десяток и более полей, то определять каждое поле и писать для него однотипное свойство было бы утомительно. Поэтому в .NET были добавлены автоматические свойства. Они имеют сокращенное объявление:
На самом деле тут также создаются поля для свойств, только их создает не программист в коде, а компилятор автоматически генерирует при компиляции.
В чем преимущество автосвойств, если по сути они просто обращаются к автоматически создаваемой переменной, почему бы напрямую не обратиться к переменной без автосвойств? Дело в том, что в любой момент времени при необходимости мы можем развернуть автосвойство в обычное свойство, добавить в него какую-то определенную логику.
Стоит учитывать, что нельзя создать автоматическое свойство только для записи, как в случае со стандартными свойствами.
Автосвойствам можно присвоить значения по умолчанию (инициализация автосвойств):
И если мы не укажем для объекта Person значения свойств Name и Age, то будут действовать значения по умолчанию.
Автосвойства также могут иметь модификаторы доступа:
Мы можем убрать блок set и сделать автосвойство доступным только для чтения. В этом случае для хранения значения этого свойства для него неявно будет создаваться поле с модификатором readonly, поэтому следует учитывать, что подобные get-свойства можно установить либо из конструктора класса, как в примере выше, либо при инициализации свойства:
Блок init
Начиная с версии C# 9.0 сеттеры в свойствах могут определяться с помощью оператора init (от слова «инициализация» — это есть блок init призван инициализировать свойство). Для установки значений свойств с init можно использовать только инициализатор, либо конструктор, либо при объявлении указать для него значение. После инициализации значений подобных свойств их значения изменить нельзя — они доступны только для чтения. В этом плане init-свойства сближаются со свойствами для чтения. Разница состоит в том, что init-свойства мы также можем установить в инициализаторе (свойства для чтения установить в инициализаторе нельзя). Например:
В данном случае класс Person для свойства Name вместо сеттера использует оператор init . В итоге на строке
предполагается создание объекта с инициализацией всех его свойств. В данном случае свойство Name получит в качестве значения строку «Undefined». Однако поскольку инициализация свойства уже произошла, то на строке
мы получим ошибку.
Как можно установить подобное свойство? Выше продемонстрирован один из способов — установка значения при определении свойства. Второй способ — через конструктор:
Третий способ — через инициализатор:
В принцпе есть еще четвертый способ — установка через другое свойство с модификатором init :
В данном случае в init-свойстве Name разворачивается в полное свойство, которое управляет полем для чтения name . Благодаря этому перед установкой значения свойства мы можем произвести некоторую предобработку. Кроме того, в выражении init устанавливается другое init-свойство — Email, которое для установки значения использует значение свойства Name — из имени получаем значение для электронного адреса.
Причем если при объявлении свойства указано значение, то в конструкторе мы можем его изменить. Значение, установленное в конструкторе, можно изменить в инициализаторе. Однако дальше процесс инициализации заканчивается. И значение не может быть изменено.
Сокращенная запись свойств
Как и методы, мы можем сокращать определения свойств. Поскольку блоки get и set представляют специальные методы, то как и обычные методы, если они содержат одну инструкцию, то мы их можем сократить с помощью оператора => :
Также можно сокращать все свойство в целом:
модификатор required
Модификатор required (добавлен в C# 11) указывает, что поле или свойства с этим модификатором обязательно должны быть инициализированы. Например, в следующем примере мы получим ошибку:
Здесь свойства Name и Age отмечены как обязательные для инициализации с помощью модификатора required , поэтому необходимо использовать инициализатор для их инициализации:
Причем не важно, устанавливаем эти свойства в конструкторе или инициализируем при определении, все равно надо использовать инициализатор для установки их значений. Например, в следующем примере мы получим ошибку:
How to use get and set accessors in C#?

The third step is optional because we can have a read-only property.
What does < get; set; >syntax mean in C#?
In C# classes it's very common to see < get; set; >code.
The < get; set; >syntax in C# is a shorthand for the automatic property.
The < get; set; >syntax in C# is a shorthand way of defining a property with both a getter and a setter method. It allows you to define a property without explicitly declaring the getter and setter methods.
This syntax doesn't explicitly define bodies for get and set accessors:
Instead, it provides a default implementation. This code is logically equivalent to:
The only difference between using the "get set syntax" and explicit private variable implementation is that with automatic properties we cannot access the private variable.
With the "get set syntax", the compiler takes care of the implementation:

Property initializers
C# 6.0 introduced property initializers. Property initializers let us define the default value for the automatic properties.
To use property initializers in C#:
- Define the property accessor type and name.
- Use the < get; set; >syntax.
- Pass the default value using the equal operator = ;
The default value of the property above is 10.
How to make the automatic property Read-only?
To make the automatic property read-only, we omit the set modifier:
In the code above, the Age property is now read-only.
We can only access it in the constructor:
Why do we use properties in C#?
1. Data validation
The main use of properties is data validation. For example, we can add logic that prevents setting the age property to a negative value:
2. Encapsulation
We use the private variable to hold the value locally. It provides encapsulation and lets us build the internal implementation without affecting outside code.
3. Raising events
Another use of get and set accessors in C# is raising events. We often want to perform action based on change. For example, "if order status changes to shipped, send an email". Set accessors are a great place to raise those events because they are the only point where object can change. So you don't have to duplicate the code by having it just before the setter call.
What is encapsulation in C#?
In C#, encapsulation is a design principal that separates the external behavior from the internal implementation. We use encapsulation to group related logic in a meaningful way. For example, we can group customer information in a Customer object. That object can store information that we don't want other areas of code to access, for example, password. So, we use a combination of accessor properties and modifiers to define the level of encapsulation. It defines how accessible a piece of information should be.
Do private variables need to have underscore in C#?
Private variables in C# don't have to be named with underscore. Adding an underscore to the name of a private variable is a naming convention, but not a requirement. Your code will run without errors even if you don't use the underscore prefix.
Зачем нужны get и set?
Зачем нужны автоматические свойства?
Я прочел все темы в этом форуме касательно свойств. Но никто толком не может ответить зачем нужны.
Зачем нужны
Объясните пожалуйста чайнику, зачем нужны и что это такое, аксессоры get и set, заранее спасибо!) .
Зачем нужны "set" и "get" в классах
Зачем нужны "set’еры" и "get’еры", если к public членам можно обращаться через указатель на класс.
если не ошибаюсь то не хватает аргументов к get и set
Добавлено через 18 секунд
или вместо точно не скажу
Добавлено через 1 минуту
get и set это свойства вроде как. простите за неточность просто мозг на работе устал
CyberIslam, даже не знаю, что написать. n/c
| Меню пользователя Psilon |
| Читать блог |
Сообщение было отмечено CyberIslam как решение
Решение
Сообщение от CyberIslam
Хм, ну тут будет сложно))
Я конечно не спец в C#, но если что, меня специалисты поправят))
Если не нужно делать никаких проверок, то разницы в принципе никакой (грубо говоря).
Дело в том, что поле с get set является свойством. Cвойство, это что то среднее между методом и полем Копмилятор смотрит на свойство как на методы, а именно он видит методы get_a и set_a +еще приватный int a. Если поле без get set — то компилятор видит это как одно поле.