Свойство в языке С# – это член класса, который предоставляет механизм доступа к полю класса (чтение и запись). При использовании свойства, мы обращаемся к нему, как к полю класса, но на самом деле вызывается соответствующий неявный метод, называемый аксессором (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}: Введите оценку за экзамен от 0 до 10: ", examen.Name); // записываем в поле, используя аксессор set examen.Rating = Convert.ToInt32(Console.ReadLine()); // читаем поле, используя аксессор get Console.WriteLine("В зачетку: {0}", 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).
Автоматические свойства
Автоматическим называют свойство, которое, в отличие от обычного свойства, уже определяет место в памяти (создает неявное поле), но при этом не позволяет создавать логику доступа. Структура объявления::
[модификатор доступа] [тип] [имя_свойства] { get; set; }
У аксессоров таких свойств отсутствует тело. Пример использования:
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: Наш Чат, в котором вы можете обсудить любые вопросы, идеи, поделиться опытом или связаться с администраторами.
Алла! А еще понятнее будет, когда чаще будете использовать свойства в своих программах, посмотрите еще пример.
Хорошо изложено, все понятно.