Какие методы есть у свойства

Свойства
Последнее обновление: 03.10.2019
Кроме обычных методов в языке C# предусмотрены специальные методы доступа, которые называют свойства.
Они обеспечивают простой доступ к полям классов и структур, узнать их значение или выполнить их установку.
Стандартное описание свойства имеет следующий синтаксис:
[модификатор_доступа] возвращаемый_тип произвольное_название
{
// код свойства
}
Например:
class Person
{
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
Здесь у нас есть закрытое поле name и есть общедоступное свойство Name. Хотя они имеют практически одинаковое название за исключением регистра,
но это не более чем стиль, названия у них могут быть произвольные и не обязательно должны совпадать.
Через это свойство мы можем управлять доступом к переменной name. Стандартное определение свойства содержит блоки get
и set. В блоке get мы возвращаем значение поля, а в блоке set устанавливаем. Параметр value представляет передаваемое значение.
Мы можем использовать данное свойство следующим образом:
Person p = new Person();
// Устанавливаем свойство – срабатывает блок Set
// значение “Tom” и есть передаваемое в свойство value
p.Name = “Tom”;
// Получаем значение свойства и присваиваем его переменной – срабатывает блок Get
string personName = p.Name;
Возможно, может возникнуть вопрос, зачем нужны свойства, если мы можем в данной ситуации обходиться обычными полями класса? Но свойства
позволяют вложить дополнительную логику, которая может быть необходима, например, при присвоении переменной класса какого-либо значения.
Например, нам надо установить проверку по возрасту:
class Person
{
private int age;
public int Age
{
set
{
if (value < 18)
{
Console.WriteLine(“Возраст должен быть больше 17”);
}
else
{
age = value;
}
}
get { return age; }
}
}
Если бы переменная age была бы публичной, то мы могли бы передать ей извне любое значение, в том числе отрицательное. Свойство же позволяет скрыть данные объекты и
опосредовать к ним доступ.
Блоки set и get не обязательно одновременно должны присутствовать в свойстве. Если свойство определяют только блок get, то такое свойство доступно только для
чтения – мы можем получить его значение, но не установить. И, наоборот, если свойство имеет только блок set, тогда это свойство доступно только для записи – можно
только установить значение, но нельзя получить:
class Person
{
private string name;
// свойство только для чтения
public string Name
{
get
{
return name;
}
}
private int age;
// свойство только для записи
public int Age
{
set
{
age = value;
}
}
}
Хотя в примерах выше свойства определялись в классе, но точно также мы можем определять и использовать свойства в структурах.
Модификаторы доступа
Мы можем применять модификаторы доступа не только ко всему свойству, но и к отдельным блокам – либо get, либо set:
class Person
{
private string name;
public string Name
{
get
{
return name;
}
private set
{
name = value;
}
}
public Person(string name)
{
Name = name;
}
}
Теперь закрытый блок set мы сможем использовать только в данном классе – в его методах, свойствах, конструкторе, но никак не в другом классе:
Person p = new Person(“Tom”);
// Ошибка – set объявлен с модификатором private
//p.Name = “John”;
Console.WriteLine(p.Name);
При использовании модификаторов в свойствах следует учитывать ряд ограничений:
Модификатор для блока set или get можно установить, если свойство имеет оба блока (и set, и get)
Только один блок set или get может иметь модификатор доступа, но не оба сразу
Модификатор доступа блока set или get должен быть более ограничивающим, чем модификатор доступа свойства. Например,
если свойство имеет модификатор public, то блок set/get может иметь только модификаторы protected internal, internal, protected, private
Автоматические свойства
Свойства управляют доступом к полям класса. Однако что, если у нас с десяток и более полей, то определять каждое поле и писать для него однотипное свойство
было бы утомительно. Поэтому в фреймворк .NET были добавлены автоматические свойства. Они имеют сокращенное объявление:
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
На самом деле тут также создаются поля для свойств, только их создает не программист в коде, а компилятор автоматически генерирует при компиляции.
В чем преимущество автосвойств, если по сути они просто обращаются к автоматически создаваемой переменной, почему бы напрямую не обратиться к переменной без автосвойств?
Дело в том, что в любой момент времени при необходимости мы можем развернуть автосвойство в обычное свойство, добавить в него какую-то определенную логику.
Стоит учитывать, что нельзя создать автоматическое свойство только для записи, как в случае со стандартными свойствами.
Автосвойствам можно присвоить значения по умолчанию (инициализация автосвойств):
class Person
{
public string Name { get; set; } = “Tom”;
public int Age { get; set; } = 23;
}
class Program
{
static void Main(string[] args)
{
Person person = new Person();
Console.WriteLine(person.Name); // Tom
Console.WriteLine(person.Age); // 23
Console.Read();
}
}
И если мы не укажем для объекта Person значения свойств Name и Age, то будут действовать значения по умолчанию.
Стоит отметить, что в структурах мы не можем использовать инициализацию автосвойств.
Автосвойства также могут иметь модификаторы доступа:
class Person
{
public string Name { private set; get;}
public Person(string n)
{
Name = n;
}
}
Мы можем убрать блок set и сделать автосвойство доступным только для чтения. В этом случае для хранения значения этого свойства для него неявно будет создаваться поле с модификатором readonly, поэтому следует учитывать, что подобные get-свойства
можно установить либо из конструктора класса, как в примере выше, либо при инициализации свойства:
class Person
{
public string Name { get;} = “Tom”
}
Сокращенная запись свойств
Как и методы, мы можем сокращать свойства. Например:
class Person
{
private string name;
// эквивалентно public string Name { get { return name; } }
public string Name => name;
}
Источник
- 03/10/2017
- Чтение занимает 4 мин
В этой статье
Свойство — это член, предоставляющий гибкий механизм для чтения, записи или вычисления значения частного поля.A property is a member that provides a flexible mechanism to read, write, or compute the value of a private field. Свойства можно использовать, как если бы они были членами общих данных, но фактически они представляют собой специальные методы, называемые методами доступа.Properties can be used as if they are public data members, but they are actually special methods called accessors. Это позволяет легко получать доступ к данным и помогает повысить безопасность и гибкость методов.This enables data to be accessed easily and still helps promote the safety and flexibility of methods.
Общие сведения о свойствахProperties overview
Свойства позволяют классу предоставлять общий способ получения и задания значений, скрывая при этом код реализации или проверки.Properties enable a class to expose a public way of getting and setting values, while hiding implementation or verification code.
Метод доступа get используется для возврата значения свойства, а метод доступа set — для присвоения нового значения.A get property accessor is used to return the property value, and a set property accessor is used to assign a new value. Эти методы доступа могут иметь различные уровни доступа.These accessors can have different access levels. Дополнительные сведения см. в разделе Доступность методов доступа.For more information, see Restricting Accessor Accessibility.
Ключевое слово value используется для определения значения, присваиваемого методом доступа set.The value keyword is used to define the value being assigned by the set accessor.
Свойства могут быть доступны для чтения и записи (они имеют оба метода доступа — get и set), только для чтения (они имеют метод доступа get, но не имеют метода доступа set) или только для записи (они имеют метод доступа set, но не имеют метода доступа get).Properties can be read-write (they have both a get and a set accessor), read-only (they have a get accessor but no set accessor), or write-only (they have a set accessor, but no get accessor). Свойства только для записи встречаются редко и чаще всего используются для ограничения доступа к конфиденциальным данным.Write-only properties are rare and are most commonly used to restrict access to sensitive data.
Простые свойства, не требующие пользовательского кода метода доступа, можно реализовать как определения текста выражений или как автоматически реализуемые свойства.Simple properties that require no custom accessor code can be implemented either as expression body definitions or as auto-implemented properties.
Свойства с резервными полямиProperties with backing fields
Одной из базовых схем реализации свойств является использование закрытого резервного поля для установки и извлечения значения свойства.One basic pattern for implementing a property involves using a private backing field for setting and retrieving the property value. Метод доступа get возвращает значение закрытого поля, а метод доступа set может выполнять определенные проверки данных до присвоения значению закрытого поля.The get accessor returns the value of the private field, and the set accessor may perform some data validation before assigning a value to the private field. Оба метода доступа также могут выполнять некоторые преобразования или вычисления данных до их сохранения или возвращения.Both accessors may also perform some conversion or computation on the data before it is stored or returned.
Это показано в следующем примере.The following example illustrates this pattern. В этом примере класс TimePeriod представляет интервал времени.In this example, the TimePeriod class represents an interval of time. На внутреннем уровне класс сохраняет интервал времени в секундах в закрытом поле с именем _seconds.Internally, the class stores the time interval in seconds in a private field named _seconds. Свойство чтения и записи с именем Hours позволяет клиенту указывать временной интервал в часах.A read-write property named Hours allows the customer to specify the time interval in hours. Методы доступа get и set выполняют необходимое преобразование между часами и секундами.Both the get and the set accessors perform the necessary conversion between hours and seconds. Кроме того, метод доступа set проверяет данные и создает ArgumentOutOfRangeException, если указано недопустимое количество часов.In addition, the set accessor validates the data and throws an ArgumentOutOfRangeException if the number of hours is invalid.
using System;
class TimePeriod
{
private double _seconds;
public double Hours
{
get { return _seconds / 3600; }
set {
if (value < 0 || value > 24)
throw new ArgumentOutOfRangeException(
$”{nameof(value)} must be between 0 and 24.”);
_seconds = value * 3600;
}
}
}
class Program
{
static void Main()
{
TimePeriod t = new TimePeriod();
// The property assignment causes the ‘set’ accessor to be called.
t.Hours = 24;
// Retrieving the property causes the ‘get’ accessor to be called.
Console.WriteLine($”Time in hours: {t.Hours}”);
}
}
// The example displays the following output:
// Time in hours: 24
Определения текста выраженийExpression body definitions
Как правило, методы доступа к свойствам состоят из однострочных операторов, которые просто назначают или возвращают результат выражения.Property accessors often consist of single-line statements that just assign or return the result of an expression. Эти свойства можно реализовать как члены, воплощающие выражение.You can implement these properties as expression-bodied members. Определения текста выражений состоят из символа =>, за которым идет выражение, назначаемое свойству или извлекаемое из него.Expression body definitions consist of the => symbol followed by the expression to assign to or retrieve from the property.
Начиная с версии C# 6 свойства только для чтения могут реализовывать метод доступа get как член, воплощающий выражение.Starting with C# 6, read-only properties can implement the get accessor as an expression-bodied member. В этом случае не используется ни ключевое слово метода доступа get, ни ключевое слово return.In this case, neither the get accessor keyword nor the return keyword is used. В следующем примере показана реализация свойства только для чтения Name в виде члена, воплощающего выражение.The following example implements the read-only Name property as an expression-bodied member.
using System;
public class Person
{
private string _firstName;
private string _lastName;
public Person(string first, string last)
{
_firstName = first;
_lastName = last;
}
public string Name => $”{_firstName} {_lastName}”;
}
public class Example
{
public static void Main()
{
var person = new Person(“Magnus”, “Hedlund”);
Console.WriteLine(person.Name);
}
}
// The example displays the following output:
// Magnus Hedlund
Начиная с C# 7.0 методы доступа get и set можно реализовывать в виде членов, воплощающих выражения.Starting with C# 7.0, both the get and the set accessor can be implemented as expression-bodied members. В этом случае необходимо указывать ключевые слова get и set.In this case, the get and set keywords must be present. В следующем примере показано использование определений текста выражений для обоих методов доступа.The following example illustrates the use of expression body definitions for both accessors. Обратите внимание, что ключевое слово return не используется с методом доступа get.Note that the return keyword is not used with the get accessor.
using System;
public class SaleItem
{
string _name;
decimal _cost;
public SaleItem(string name, decimal cost)
{
_name = name;
_cost = cost;
}
public string Name
{
get => _name;
set => _name = value;
}
public decimal Price
{
get => _cost;
set => _cost = value;
}
}
class Program
{
static void Main(string[] args)
{
var item = new SaleItem(“Shoes”, 19.95m);
Console.WriteLine($”{item.Name}: sells for {item.Price:C2}”);
}
}
// The example displays output like the following:
// Shoes: sells for $19.95
Автоматически реализуемые свойстваAuto-implemented properties
В некоторых случаях свойство get и методы доступа set просто присваивают значение резервному полю или извлекают значение из него без включения дополнительной логики.In some cases, property get and set accessors just assign a value to or retrieve a value from a backing field without including any additional logic. С помощью автоматически реализуемых свойств можно упростить код, в то время как компилятор C# будет прозрачно предоставлять вам резервное поле.By using auto-implemented properties, you can simplify your code while having the C# compiler transparently provide the backing field for you.
Если у свойства есть методы доступа get и set, они оба должны быть автоматически реализованы.If a property has both a get and a set accessor, both must be auto-implemented. Автоматически реализуемое свойство определяется с помощью ключевых слов get и set без указания какой-либо реализации.You define an auto-implemented property by using the get and set keywords without providing any implementation. Следующий пример аналогичен предыдущему, за исключением того, что Name и Price являются автоматически реализуемыми свойствами.The following example repeats the previous one, except that Name and Price are auto-implemented properties. Обратите внимание на то, что в этом примере также удаляется параметризованный конструктор, что позволяет инициализировать объекты SaleItem, вызывая конструктор без параметров и инициализатор объекта.Note that the example also removes the parameterized constructor, so that SaleItem objects are now initialized with a call to the parameterless constructor and an object initializer.
using System;
public class SaleItem
{
public string Name
{ get; set; }
public decimal Price
{ get; set; }
}
class Program
{
static void Main(string[] args)
{
var item = new SaleItem{ Name = “Shoes”, Price = 19.95m };
Console.WriteLine($”{item.Name}: sells for {item.Price:C2}”);
}
}
// The example displays output like the following:
// Shoes: sells for $19.95
Использование свойствUsing Properties
Свойства интерфейсаInterface Properties
Сравнение свойств и индексаторовComparison Between Properties and Indexers
Ограничение доступности методов доступаRestricting Accessor Accessibility
Автоматически реализуемые свойстваAuto-Implemented Properties
Спецификация языка C#C# Language Specification
Дополнительные сведения см. в разделе Свойства в Спецификации языка C#.For more information, see Properties in the C# Language Specification. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.The language specification is the definitive source for C# syntax and usage.
См. такжеSee also
- Руководство по программированию на C#C# Programming Guide
- Использование свойствUsing Properties
- ИндексаторыIndexers
- Ключевое слово getget keyword
- Ключевое слово setset keyword
Источник
Общая структура типа C# представляет собой описание типа и определение полей и методов. Поля – хранят данные, методы ими манипулируют (изменяют значения).
Свойства созданы как комбинация метода и поля в одном члене типа для лаконичности и безопасности кода.
Лаконичность достигается тем, что для считывания или изменения значения поля в свойствах используются два метода. Безопасность – ограничением доступа к полям типа только свойствами. Для программиста типа, свойство выглядит методом, поскольку его нужно определять и реализовывать. Для программиста использующего объект типа – полем, поскольку обращение к полю и свойству идентичны. Инкапсуляция.
Для доступа к значению поля в свойстве используются методы, которые создаются средой выполнения, но реализуются программистом. Их два – get и set. Get используется в случае чтения значения поля и называется акссесором, set – при изменении значения, называется мутатором. Общее название для мутатора и аксессора – методы доступа.
Объявление свойства
Методы определяются внутри блока типа. Сигнатура в последовательности при объявлении:
уровень доступа;
тип свойства;
имя свойства.
После сигнатуры определения следует два блока кода с реализацией аксессора и/или мутатора:
public class GrandMa
{
private int fullAge = 69; / закрытое поле для хранения возраста. Доступ к полю возможен только из свойства и методов класса.
public int FullAge
{
get
{
return fullAge;
}
set
{
if (value > 0)
{
fullAge = value;
}
}
}
}
Допустимо реализовывать свойство только с одним из методов. Свойство, содержащее только аксессор называется полем только для чтения, свойство с одним мутатором – свойством только для записи.
Аксессор get
Если в свойстве использован акссессор, то подобно методу, свойство должно возвращать значение поля, которое акссессор считывает. Тип поля должен соответствовать типу возвращаемого значения свойства.
Блок кода аксессора похож на реализацию метода и выполняется по всем правилам синтаксиса С#. Пример объявления свойства только с аксессором:
class Elephant
{
private string elName; // Закрытое поле. Считывание значения возможно только методами и свойствами класса.
public string ElName // открытое свойство для считывания значения поля elName. Возвращает значение типа string.
{
// реализация аксессора
get
{
return elName; // возврат значения поля elName
}
}
}
Использование аксессора в пользовательском в коде эквивалентно считыванию на прямую из поля:
Elephant el1 = new Elephant();// создание объекта типа Elephant
System.Console.WriteLine(el1.ElName); // вывод значения поля elName на системную консоль
В блоке реализации аксессора можно менять значение считываемого поля, но крайне не рекомендуется, поскольку это может иметь массу побочных эффектов, которые при увеличении объёма кода трудно отследить:
class Elephant
{
private string elName; // Закрытое поле. Считывание значения возможно только методами и свойствами класса.
public string ElName // открытое свойство для считывания значения поля elName. Возвращает значение типа string.
{
// реализация аксессора
get
{
return elName + “ Сидорович”; // возврат значения поля elName с изменением. Изменения будут происходить при каждом использовании свойства внутри объекта. Плохой стиль, для изменения значения лучше использовать мутатор.
}
}
}
Мутатор set
Мутатор, или метод set по спецификации вызова поход на метод с возвращаемым значение типа void и одним параметром. public void SetValue (object value). Среда выполнения сама его вызывает в точке указанной программистом с прописанной им реализацией.
При реализации мутатора в блоке кода свойства нужно помнить о неявном участии параметра value, который выполняет функцию буфера, промежуточной переменной, значение которой нужно предать полю типа.
Пример реализации:
class Elephant
{
private string elName; // Закрытое поле. Считывание значения возможно только методами и свойствами класса.
public string ElName // открытое свойство для считывания значения поля elName. Возвращает значение типа string.
{
get
{
return elName;
}
// Реализация мутатора
set
{
elName = value; // полю elName присваивается значение неявного параметра value.
}
}
}
В блоке кода мутатора нельзя вводить локальную переменную value, поскольку уже есть такая переменная, неявно переданная в виде параметра. Такой код компилятор не пропустит и выдаст ошибку:
class Elephant
{
private string elName; // Закрытое поле. Считывание значения возможно только методами и свойствами класса.
public string ElName // открытое свойство для считывания значения поля elName. Возвращает значение типа string.
{
// Реализация мутатора
set
{
String value = “Фыва”; // нельзя, параметр value уже определен.
elName = value; // полю elName присваивается значение неявного параметра value.
}
}
}
Метод доступа set используется неявно при присвоении значения свойству, как в следующем примере:
Elephant el1 = new Elephant();// создание объекта типа Elephant
El1.ElName = “Никки”; // присваиваем значение полю elName через свойство ElName неявно вызывается мутатор.
System.Console.WriteLine(el1.ElName); // вывод значения поля elName на системную консоль
Модификаторы свойств и уровни доступа
Свойства, подобно типам в которых определяются по уровню доступа могут быть: открытыми (public), частными (private), защищенными (protected). Доступ к методам свойства осуществляется в соответствии с модификатором.
Свойство может быть статичным (static), и будет доступным без необходимости создавать экземпляр типа, в котором оно определено.
Допустимо объявлять свойства виртуальными, для возможности их переопределения в производных классах с помощью ключевого слова override или переопределения и запечатывания при помощи ключевого слова sealed.
Свойство можно сделать абстрактным при помощи ключевого слова abstract, оставив блок реализации пустым, в дальнейшем реализовав свойство в дочерних (производных) классах.
Применительно к определению свойств запрещено одновременное употребление следующих пар модификаторов:
static – virtual;
static – abstract;
static – override.
Допустимо использовать разные уровни доступа для аксессора и мутатора, что бывает удобно, если нужно обеспечить доступность чтения поля, но при этом защитить его от записи методами производных классов.
Пример:
private string description = “Какое-то описание”;
// создаем свойство для чтения/записи значения в поле description с разными модификаторами доступа для аксессора и мутатора
public string Description
{
// открытый аксессор
get
{
return description;
}
// защищенный мутатор
protected set
{
description = value;
}
}
Если для одного из методов доступа не указан модификатор доступа, то компилятор вставит его неявно руководствуясь модификатором доступа свойства.
Автоматически реализуемые свойства
Программист при реализации свойства связывает его с полем. Часто поля и свойства имеют одинаковые имена, чтобы программист, взглянув, мог сразу догадаться, для работы с каким полем создано свойство.
При работе с типами, в которых реализованы свойства, поля вовсе не вызываются, поскольку любой доступ к ним организован через свойства. Зачем в таком случае создавать поля вручную? И если код свойств не требует изысков программирования, то не проще ли доверить их создание компилятору.
Автоматически реализуемые свойства – это свойства, которые автоматически реализует компилятор, он же создает и поле, для доступа к которому создается свойство.
Сигнатура определения автоматически реализуемого свойства:
тип имя { get; set; }
Сам блок инструкций в таком свойстве отсутствует и для мутатора и для аксессора. После ключевых слов get и set ставится символ завершения инструкции «;».
Автоматически реализуемые свойства доступны в версии C# 3.0 и новее. С 6 версии спецификации языка доступна возможность объявить и инициализировать скрытое поле через упрощенный синтаксис свойства, вот так:
public string Nickname { get; set; } = “Забияка”;
Источник