Свойства объектов си шарп

Использование свойств (Руководство по программированию в C#)

Свойства сочетают в себе возможности полей и методов. Пользователю объекта свойство представляется как поле, и для доступа к нему применяется тот же синтаксис. При реализации класса свойство представляется в виде одного или двух блоков кода для методов доступа get и (или) set. Блок кода для get метода доступа выполняется при чтении свойства; блок кода для set метода доступа выполняется, когда свойству присваивается значение. Свойство без метода доступа set доступно только для чтения. Свойство без метода доступа get доступно только для записи. Свойство, для которого определены оба этих метода, доступно для чтения и записи. В C# 9 и более поздних версий можно использовать метод доступа init вместо set , чтобы сделать свойство доступным только для чтения.

В отличие от полей, свойства не классифицируются как переменные. Таким образом, нельзя передать свойство в качестве параметра ref или out .

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

При объявлении свойств в блоке класса указывается уровень доступа поля, затем тип и имя свойства, а после этого блок кода, в котором объявляются методы доступа get и (или) set . Пример:

public class Date < private int _month = 7; // Backing store public int Month < get =>_month; set < if ((value >0) && (value < 13)) < _month = value; >> > > 

В этом примере Month объявляется как свойство, а метод доступа set обеспечивает установку значения Month в диапазоне от 1 до 12. Для отслеживания фактического значения свойство Month использует частное поле. Реальное расположение данных свойства часто называют резервным хранилищем свойства. Свойства часто используют частные поля в качестве резервного хранилища. Поле помечается как частное для того, чтобы гарантировать возможность его изменения только посредством вызова свойства. Дополнительные сведения об ограничениях открытого и закрытого доступа см. в разделе Модификаторы доступа.

Читайте также:  Html link rel prefetch

Автоматически реализуемые свойства поддерживают упрощенный синтаксис для простых объявлений свойств. Дополнительные сведения см. в разделе Автоматически реализуемые свойства.

Метод доступа get

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

class Employee < private string _name; // the name field public string Name =>_name; // the Name property > 

При ссылке на свойство (кроме случаев, когда свойство является целью присваивания) вызывается метод доступа get , который считывает значение свойства. Пример:

var employee= new Employee(); //. System.Console.Write(employee.Name); // the get accessor is invoked here 

Метод get доступа должен заканчиваться оператором return или throw , и управление не может передаваться из тела метода доступа.

Изменение состояния объекта с помощью метода доступа является неправильным стилем программирования get .

Метод доступа get можно использовать для возврата значения поля напрямую или после вычисления. Пример:

class Manager < private string _name; public string Name =>_name != null ? _name : "NA"; > 

Если в предыдущем сегменте кода не присвоить значение свойству Name , он вернет значение NA .

Метод доступа set

Метод доступа set похож на метод с типом возвращаемого значения void. В нем используется неявный параметр value , тип которого соответствует типу свойства. В следующем примере метод доступа set добавляется к свойству Name :

class Student < private string _name; // the name field public string Name // the Name property < get =>_name; set => _name = value; > > 

При присвоении значения свойству вызывается метод доступа set с аргументом, содержащим новое значение. Пример:

var student = new Student(); student.Name = "Joe"; // the set accessor is invoked here System.Console.Write(student.Name); // the get accessor is invoked here 

Использование неявного имени value параметра для объявления локальной переменной в методе доступа является ошибкой set .

Метод доступа init

Код для создания метода доступа init аналогичен коду для создания метода доступа set , за исключением того, что используется ключевое слово init вместо set . Различие заключается в том, что метод доступа init можно использовать только в конструкторе или с помощью инициализатора объекта.

Комментарии

Свойства могут быть помечены как public , private , protected , internal , protected internal или private protected . Эти модификаторы доступа определяют, каким образом пользователи класса смогут получать доступ к свойству. Методы доступа get и set для одного свойства могут иметь разные модификаторы доступа. Например, метод доступа get может иметь модификатор public , разрешающий доступ из-за пределов типа только для чтения, а метод доступа set — модификатор private или protected . Дополнительные сведения см. в статье Модификаторы доступа.

Свойство может быть объявлено как статическое с помощью ключевого слова static . Статические свойства доступны вызывающим элементам в любое время, даже если экземпляр класса не существует. Дополнительные сведения см. в статье Статические классы и члены статических классов.

Свойство может быть помечено как виртуальное с помощью ключевого слова virtual. Виртуальные свойства позволяют производным классам переопределять поведение свойства с помощью ключевое слово переопределения. Дополнительные сведения об этих параметрах см. в разделе Наследование.

Свойство, переопределяющее виртуальное свойство, также может быть запечатано, указывая, что для производных классов оно больше не является виртуальным. Наконец, свойство можно объявить абстрактным (abstract). Абстрактные свойства не определяют реализацию в классе , и производные классы должны писать собственную реализацию. Дополнительные сведения об этих параметрах см. в разделе Абстрактные и запечатанные классы и члены классов.

Использование модификаторов virtual, abstract или override в методе доступа статического (static) свойства является ошибкой.

Примеры

В этом примере демонстрируются свойства экземпляра, а также статические и доступные только для чтения свойства. Этот метод принимает введенное с клавиатуры имя сотрудника, увеличивает значение NumberOfEmployees на 1, после чего отображает имя и номер сотрудника.

public class Employee < public static int NumberOfEmployees; private static int _counter; private string _name; // A read-write instance property: public string Name < get =>_name; set => _name = value; > // A read-only static property: public static int Counter => _counter; // A Constructor: public Employee() => _counter = ++NumberOfEmployees; // Calculate the employee's number: > 

Пример скрытого свойства

В этом примере демонстрируется доступ к свойству базового класса, которое скрыто в производном классе другим свойством с таким же именем:

public class Employee < private string _name; public string Name < get =>_name; set => _name = value; > > public class Manager : Employee < private string _name; // Notice the use of the new modifier: public new string Name < get =>_name; set => _name = value + ", Manager"; > > class TestHiding < public static void Test() < Manager m1 = new Manager(); // Derived class property. m1.Name = "John"; // Base class property. ((Employee)m1).Name = "Mary"; System.Console.WriteLine("Name in the derived class is: ", m1.Name); System.Console.WriteLine("Name in the base class is: ", ((Employee)m1).Name); > > /* Output: Name in the derived class is: John, Manager Name in the base class is: Mary */ 

На что следует обратить внимание в предыдущем примере:

    Свойство Name в производном классе скрывает свойство Name базового класса. В таком случае в объявлении свойства в производном классе используется модификатор new :

Дополнительные сведения о скрытии элементов см. в разделе Модификатор new.

Пример переопределения свойства

В этом примере два класса ( Cube и Square ) реализуют абстрактный класс Shape и переопределяют его абстрактное свойство Area . Обратите внимание на использование модификатора override в свойствах. Программа принимает введенную длину стороны, на основании которой рассчитывает площади квадрата и куба. Также принимается введенное значение площади, на основании которой рассчитываются длины сторон квадрата и куба.

abstract class Shape < public abstract double Area < get; set; >> class Square : Shape < public double side; //constructor public Square(double s) =>side = s; public override double Area < get =>side * side; set => side = System.Math.Sqrt(value); > > class Cube : Shape < public double side; //constructor public Cube(double s) =>side = s; public override double Area < get =>6 * side * side; set => side = System.Math.Sqrt(value / 6); > > class TestShapes < static void Main() < // Input the side: System.Console.Write("Enter the side: "); double side = double.Parse(System.Console.ReadLine()); // Compute the areas: Square s = new Square(side); Cube c = new Cube(side); // Display the results: System.Console.WriteLine("Area of the square = ", s.Area); System.Console.WriteLine("Area of the cube = ", c.Area); System.Console.WriteLine(); // Input the area: System.Console.Write("Enter the area: "); double area = double.Parse(System.Console.ReadLine()); // Compute the sides: s.Area = area; c.Area = area; // Display the results: System.Console.WriteLine("Side of the square = ", s.side); System.Console.WriteLine("Side of the cube = ", c.side); > > /* Example Output: Enter the side: 4 Area of the square = 16.00 Area of the cube = 96.00 Enter the area: 24 Side of the square = 4.90 Side of the cube = 2.00 */ 

См. также

Источник

Свойства в C#

Свойство в языке С# – это член класса, который предоставляет механизм доступа к полю класса (чтение и запись). При использовании свойства, мы обращаемся к нему, как к полю класса, но на самом деле вызывается соответствующий неявный метод, называемый аксессором (accessor). Существует два таких метода: get (для получения данных) и set (для записи).

Объявление простого свойства имеет следующую структуру:

 [модификатор доступа] [тип] [имя_свойства] < get < // тело аксессора для чтения из поля >set < // тело аксессора для записи в поле >>

Приведем пример использования свойств. Имеется класс Экзамен (Exam), и в нем есть закрытое поле (оценка) rating, которое не может быть ниже 0 и больше 10. Для управления доступом к этому полю будет использовано свойство Rating:

using System; namespace свойства < class Exam < public string Name; // фамилия студента private int rating; // 10б_оценка, закрытое поле public int Rating //объявление свойства < get // аксессор чтения поля с преобразованием < if (rating < 5) return 2; else return (rating+1)/2; >set // аксессор записи в поле < if (value < 0) rating = 0; else if (value >10) rating = 10; else rating = value; > > public Exam(string name) // конструктор < Name = name; >> class Program < static void Main(string[] args) < Exam examen = new Exam("Петров"); // создание объекта Console.Write("Студент - : Введите оценку за экзамен от 0 до 10: ", examen.Name); // записываем в поле, используя аксессор set examen.Rating = Convert.ToInt32(Console.ReadLine()); // читаем поле, используя аксессор get Console.WriteLine("В зачетку: ", examen.Rating); Console.ReadKey(); > > >

В свойстве Rating реализуются два метода. В теле аксессора get в итоге должно возвращаться либо значение поля, либо другое значение. В примере 10-ти бальная оценка пересчитывается в 4-х балльную: 2,3,4,5. В аксессоре же присутствует неявный параметр value, который содержит значение, присваиваемое свойству, причем полю будет присваиваться целое число от 0 до 10.
Если, например, мы бы просто сделали поле rating открытым и не использовали бы ни методы, ни свойство для доступа, то мы могли бы записать в это поле любое значение, в том числе и некорректное, а так мы можем контролировать чтение и запись.
Для контроля доступа мы могли бы использовать простые методы, но для этого нам бы пришлось реализовать два отдельных метода с разными именами, и при обращении к ним необходимо использовать скобки, что добавляет лишние неудобства.
Свойство также может предоставлять доступ только к чтению поля или только к записи. Если, например, нам необходимо закрыть доступ на запись, мы просто не указываем аксессор set. Пример:

class Exam < private int rating; public Exam(int r) // конструктор < rating = r; >public int Rating < get < return rating; >> > class Program < static void Main(string[] args) < Exam exm = new Exam(2); Console.WriteLine(exm.Rating); // чтение exm.Rating = 4; // ошибка, свойство только на чтение .  Console.ReadKey(); > >

Заметим, что само свойство не определяет место в памяти для хранения поля, и, соответственно, необходимо отдельно объявить поле, доступом к которому будет управлять свойство (например, rating и Rating).

Автоматические свойства

Автоматическим называют свойство, которое, в отличие от обычного свойства, уже определяет место в памяти (создает неявное поле), но при этом не позволяет создавать логику доступа. Структура объявления::
[модификатор доступа] [тип] [имя_свойства]
У аксессоров таких свойств отсутствует тело. Пример использования:

class Exam < public int Rating < get; set; >> class Program < static void Main(string[] args) < Exam exm = new Exam(); exm.Rating = 0; Console.WriteLine(exm.Rating); Console.ReadKey(); >>

Автоматически реализуемые свойства имеет смысл использовать тогда, когда нет необходимости накладывать какие-либо ограничения на возможные значения неявного поля свойства. Чем же они тогда предпочтительнее полей? Ответ: У таких свойств остается возможность сделать их только на чтение или только на запись. Для этого используется модификатор доступа private, указываемый перед именем аксессора:
public int Rating < private get; set; >// свойство только на запись
или
public int Rating < get; private set; >// свойство только на чтение

Обратите внимание, что значительная часть членов классов являются именно полями. Разберите также пример работы со свойствами.

NEW: Наш Чат, в котором вы можете обсудить любые вопросы, идеи, поделиться опытом или связаться с администраторами.

Источник

Оцените статью