プロパティ (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.

  • set アクセサーで割り当てる値は value キーワードを使用して定義します。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

プロパティを実装する基本的な手法の 1 つとして、プロパティ値の設定と取得にプライベート バッキング フィールドを使用する方法があります。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

プロパティ アクセサーは、通常、式の結果を割り当てるか返すだけの 1 行のステートメントで構成されます。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("Isabelle", "Butts");
      Console.WriteLine(person.Name);
   }
}
// The example displays the following output:
//      Isabelle Butts

C# 7 以降では、get アクセサーと set アクセサーのどちらも、式形式のメンバーとして実装できます。Starting with C# 7, 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. get アクセサーで return キーワードが使用されていない点に注意してください。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)
   {
      this.name = name;
      this.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. 次の例は前の例と似ていますが、NamePrice が自動実装プロパティである点が異なります。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 default 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# 言語の仕様」を参照してください。 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。

関連項目See also

C# プログラミング ガイドC# Programming Guide
プロパティの使用Using Properties
インデクサーIndexers
get キーワード get keyword
set キーワードset keyword