Get set c что это

от admin

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 , поэтому необходимо использовать инициализатор для их инициализации:

Причем не важно, устанавливаем эти свойства в конструкторе или инициализируем при определении, все равно надо использовать инициализатор для установки их значений. Например, в следующем примере мы получим ошибку:

C#. Свойства. Аксессоры get, set. Примеры классов, содержащих свойства

Свойство – это специальное поле класса, содержащее программный код доступа к внутренним переменным (полям) класса или вычисления некоторого значения. Свойства обеспечивают удобный и рациональный путь доступа к внутренней переменной в классе.

Общая форма объявления свойства в классе

  • type – тип данных возвращаемый свойством;
  • PropName – имя свойства. По этому имени идет обращение к свойству;
  • get – аксессор, который используется для чтения значения из внутреннего поля класса;
  • set – аксессор, используемый для записи значения во внутреннее поле класса. Аксессор set получает неявный параметр value , содержащий значение, которое присваивается свойству.

Если имя свойства встречается в правой части оператора присваивания или в выражении

тогда вызывается get . Здесь obj – имя экземпляра класса, в котором объявлено свойство PropName.

Если имя свойства встречается в левой части оператора присваивания

тогда вызывается аксессор set . Здесь obj – имя экземпляра класса, в котором объявлено свойство PropName .

2. Преимущества использования свойств в классах

Использование свойств в классах дает следующие преимущества:

  • обеспечивается более рациональный и естественной доступ к внутренним переменным класса;
  • в коде аксессоров можно реализовывать разного рода проверки на допустимость значений внутренних переменных класса;
  • гибкость в правах доступа к внутренней переменной: отсутствие аксесора set позволяет реализовать доступ «только для чтения» для внутренних данных класса. Это, в свою очередь, делает невозможным случайное изменение этих данных.
3. Пример свойства, реализующего чтение/запись переменной типа int

В примере демонстрируется простой случай доступа к свойству в классе. Объявляется класс с именем IntNumber в котором реализованы:

  • внутренняя скрытая ( private ) переменная типа int с именем d ;
  • конструктор с одним параметром, который инициализирует переменную d ;
  • свойство с именем Number . Это свойство содержит аксессоры get и set ;
  • метод Display для вывода значения скрытой ( private ) переменной d .
Читать:
Intel boot agent как отключить

Текст класса IntNumber и его использование в функции main() следующий (приложение типа Console Application)

Результат выполнения программы

4. Как влияют модификаторы доступа к элементам класса ( private , public) на доступ к свойству?

Чтобы использовать свойство, оно должно быть объявлено с модификатором доступа public . Если свойство объявить с модификатором доступа private , то это свойство будет недоступно. В результате, при попытке доступа к свойству, компилятор выдаст сообщение об ошибке

где PropName – имя private -свойства, объявленного в классе ClassName .

5. Пример свойства, которое реализует доступ к внутренней переменной, которая есть массивом чисел типа double

В примере объявляется класс ArrayDouble , реализующий массив вещественных чисел. В классе объявляются:

  • внутренняя скрытая ( private ) переменная A , которая есть массивом чисел типа double ;
  • два конструктора класса;
  • индексатор, который возвращает элемент массива по заданному индексу;
  • свойство Sum , которое определяет аксессоры get и set .

Текст класса ArrayDouble и его использование в методе main() , следующий

В классе ArrayDouble реализовано свойство Sum . Это свойство определяет два аксессора get и set . С целью демонстрации аксессор get реализует вычисление суммы элементов массива A

Также с помощью аксессора set в каждый элемент массива A заносится значение value/A.length

Вывод: в аксессорах get , set можно задавать дополнительные операции вычисления над данными класса. Необязательно должно возвращаться значение некоторого поля в классе.

Результат работы программы

6. Пример свойства, которое реализует доступ к структурной переменной ( struct )

В примере демонстрируется доступ к структуре типа Fracion с помощью свойств. Свойства объявляются в классе Complex , реализующем комплексное число. Класс Complex декларирует следующие элементы:

  • внутренние скрытые ( private ) переменные real , imag . Эти переменные (поля) соответствуют действительной и мнимой части комплексного числа;
  • свойство Real для чтения/записи значения поля real ;
  • свойство Imag для чтения/записи значения поля imag ;
  • свойство RealD , представляющее значение поля real в виде вещественного числа типа double . Это свойство предназначено только для чтения ( get ), аксесор set отсутствует в свойстве;
  • свойство ImagD , представляющее значение поля imag в виде вещественного числа типа double . Это свойство предназначено только для чтения ( get );
  • свойство Abs , вычисляющее модуль комплексного числа. Это свойство предназначено только для чтения.

Текст программы для приложения типа Console Application следующий

Результат работы программы

7. Пример свойства, которое реализует доступ к объекту класса

В примере демонстрируется доступ к объекту класса с помощью свойства.

Объявляется класс Point , реализуючий точку на координатной плоскости. В классе объявляются:

  • две внутренние скрытые ( private ) переменные x , y которые есть координатами точки;
  • два конструктора;
  • свойства X , Y . Эти свойства с помощью аксессоров get , set реализуют доступ к скрытым переменным x , y .

Также объявляется класс Line , который реализует линию состоящую из двух точек типа Point . В классе реализованы:

  • скрытые ( private ) внутренние переменные p1 , p2 типа Point . Это точки концов отрезка;
  • свойства P1 , P2 реализующие доступ к внутренним переменным p1 , p2 . В этих свойствах продемонстрирован возврат объекта класса типа Point ;
  • свойство Length , определяющее длину линии. Это свойство содержит только один аксессор get . Аксессор set отсутствует.

Текст демонстрационной программы, созданной по шаблону Console Application следующий

Как видно из вышеприведенного кода, в классе Line реализованы два свойства, которые осуществляют доступ к объекту класса Point

Результат выполнения программы

8. Определяют ли свойства место в памяти для полей класса?

Нет, не определяют. Свойства руководят доступом к полям. Само свойство не представляет поле (член данных) класса. Поле должно быть определено в классе независимо от свойства.

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; >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.

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 is that with automatic properties we cannot access the private variable.

That's because the compiler takes care of the implementation:

C# code for the get-set auto-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#:

  1. Define the property accessor type and name.
  2. Use the < get; set; >syntax.
  3. Pass the default value using the equal operator = ;

The default value of the property above is 10.

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 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.

Josip Miskovic is a software developer at Americaneagle.com. Josip has 10+ years in experience in developing web applications, mobile apps, and games.

I've used these principles to increase my earnings by 63% in two years. So can you.

What is the < get; set; >syntax in C#?

I am learning ASP.NET MVC and I can read English documents, but I don’t really understand what is happening in this code:

What does this mean: < get; set; >?

a3y3's user avatar

20 Answers 20

It’s a so-called auto property, and is essentially a shorthand for the following (similar code will be generated by the compiler):

So as I understand it < get; set; >is an «auto property» which just like @Klaus and @Brandon said is shorthand for writing a property with a «backing field.» So in this case:

However if you’re like me — about an hour or so ago — you don’t really understand what properties and accessors are, and you don’t have the best understanding of some basic terminologies either. MSDN is a great tool for learning stuff like this but it’s not always easy to understand for beginners. So I’m gonna try to explain this more in-depth here.

get and set are accessors, meaning they’re able to access data and info in private fields (usually from a backing field) and usually do so from public properties (as you can see in the above example).

There’s no denying that the above statement is pretty confusing, so let’s go into some examples. Let’s say this code is referring to genres of music. So within the class Genre, we’re going to want different genres of music. Let’s say we want to have 3 genres: Hip Hop, Rock, and Country. To do this we would use the name of the Class to create new instances of that class.

Now that we’ve created the instances of the Genre class we can set the genre names using the ‘Name’ property that was set way up above.

We can set the name of ‘g1’ to Hip Hop by writing the following

What’s happening here is sort of complex. Like I said before, get and set access information from private fields that you otherwise wouldn’t be able to access. get can only read information from that private field and return it. set can only write information in that private field. But by having a property with both get and set we’re able do both of those functions. And by writing g1.Name = «Hip Hop»; we are specifically using the set function from our Name property

set uses an implicit variable called value . Basically what this means is any time you see «value» within set , it’s referring to a variable; the «value» variable. When we write g1.Name = we’re using the = to pass in the value variable which in this case is «Hip Hop» . So you can essentially think of it like this:

It’s Important to note that the above example isn’t actually written in the code. It’s more of a hypothetical code that represents what’s going on in the background.

So now that we’ve set the Name of the g1 instance of Genre, I believe we can get the name by writing

and if we ran this we would get «Hip Hop» in our console.

So for the purpose of this explanation I’ll complete the example with outputs as well

Похожие статьи