Свойства (Руководство по программированию в C#)Properties (C# Programming Guide)

Свойство — это член, предоставляющий гибкий механизм для чтения, записи или вычисления значения частного поля.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



Спецификация языка 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