プロパティのアクセサーには、プロパティの取得または設定に関連する実行可能ステートメントが含まれています。アクセサー宣言には、get アクセサー、set アクセサー、またはその両方を含めることができます。宣言は次のいずれかの形式を取ります:
get {} set {}
get accessor:
get アクセサー本体はメソッド本体と似ています。プロパティ タイプの値を返す必要があります。 get アクセサーの実行は、フィールドの値を読み取ることと同じです。
以下は、プライベート フィールド名の値を返す get アクセサーです:
private string name; // the name field public string Name // the Name property { get { return name; } }
プロパティが参照されると、そのプロパティが代入のターゲットでない限り、get アクセサーが呼び出されてプロパティの値を読み取ります。
例:
Employee e1 = new Employee(); ... Console.Write(e1.Name); // The get accessor is invoked here
get アクセサーは return または throw ステートメントで終了する必要があり、制御はアクセサー本体を超えて拡張することはできません。
set アクセサー:
set アクセサーは void を返すメソッドに似ています。 value という暗黙的なパラメーターを受け取ります。このパラメーターの型はプロパティの型です。
次の例では、set アクセサーが Name プロパティに追加されます:
public string Name { get { return name; } set { name = value; } }
値がプロパティに割り当てられると、操作によって set アクセサーが呼び出されます。
例:
e1.Name = "Joe"; // The set accessor is invoked here
set アクセサーのローカル変数宣言に暗黙的なパラメーター名 (値) を使用するのはエラーです。
備考:
プロパティは、使用されるアクセサーに従って次のように分類されます:
get アクセサーのみを持つプロパティは、読み取り専用プロパティと呼ばれます。読み取り専用プロパティに値を割り当てることはできません。
set アクセサーのみを持つプロパティは、書き込み専用プロパティと呼ばれます。書き込み専用プロパティは、代入のターゲットとして以外は参照できません。
get アクセサーと set アクセサーの両方を持つプロパティは、読み取り/書き込みプロパティです。
プロパティ宣言では、get アクセサーと set アクセサーの両方をプロパティ本体内で宣言する必要があります。
get アクセサーを使用してオブジェクトの状態を変更するのは、悪いプログラミング スタイルです。
アクセサーとは何かを理解するために次の例を使用します:
using System; namespace AccessorEG { public class Student { // 私有字段 private field private int _age; // 公开的属性 public property public int Age { get { return _age; } set { _age = value; } } } class Program { static void Main(string[] args) { Student stu = new Student(); stu.Age = 10; // 使用了修改 Console.WriteLine(stu.Age.ToString()); //使用了读取 输出 10 Console.ReadKey(); } } }
アクセサーは、オブジェクト型メンバーの外部世界へのインターフェイスを指し、オブジェクト型メンバーを許可するブリッジであることを理解するのは簡単です。アクセサーを使用して外部と対話することで、外部はオブジェクト メンバーの読み取りおよび書き込みの対応する操作を実行できます。
それでは、どのメンバーがアクセサーを持つことができるのでしょうか?アクセサーは、読み取り専用以外のフィールドおよびイベントに対して宣言できます。もちろん、読み取り専用ドメインでも外部から取得できるインターフェイス、つまり get を提供できますが、初期化できるのは宣言またはコンストラクター内のみであり、set メソッドはサポートされていません。
using System; namespace AccessorEG { public class Student { // 私有字段 private field private readonly int _age = 10; // 公开的属性 public property public int Age { get { return _age; } } } class Program { static void Main(string[] args) { Student stu = new Student(); Console.WriteLine(stu.Age.ToString()); // 使用了读取 输出 10 Console.ReadKey(); } } }
上記のコードの読み取り専用フィールドの値は宣言時に割り当てられており、public 属性に対応するアクセサーで set メソッドを提供できません。それ以外の場合はコンパイルされませんが、設定することはできます。外の世界から得られるもの。
フィールドのアクセサーについて、一般的なものは次のとおりです。
using System; namespace AccessorEG { public class Student { #region 全访问权限 // 私有字段 private int _age; // 与_age对应的公开属性,包含了set和get方法 public int Age { get { return _age; } set { _age = value; } } // 如果您安装了.NET3.0,那么您可以使用自动属性,届时,上面的代码即可以下面的代替 // 在VS.NET下输入 prop 连击两下Tab键,编译器会自动帮您生成自动属性 // public int Age { get; set; } #endregion // 全访问权限 #region 只读属性 private string _name; public string Name { get { return _name; } } // 等同于 // public string Name { private set; get; } #endregion #region 只写属性 private bool _sex; public bool Sex { set { _sex = value; } } // 等同于 // public bool Sex { set; private get; } #endregion } class Program { static void Main(string[] args) { Student stu = new Student(); stu.Age = 18; // stu.Name = "Johness"; 异常,编译错误,因为该属性只读 // Console.WriteLine(stu.Sex.ToString()); 异常,编译错误,因为该属性只写 Console.WriteLine(stu.Age.ToString()); // 使用了读取 Console.ReadKey(); // 输出 18 } } }
上記の例の読み取り専用と書き込み専用は、明示的に所有者を指定した場合にのみ有効です。アクセサー、つまりクラスのプライベート フィールドです。その後、クラス内では、読み取りおよび書き込み操作用に定義したプライベート フィールドを引き続き便利に使用できます。そのため、友人には、3.0 の新しい構文 (自動属性) ではなく .NET2.0 の構文を使用してフィールドとそのアクセサーを定義することをお勧めします。 )。もちろん、アクセサーを使用してデータの有効性をより適切に検証することもできます:
using System; namespace AccessorEG { public class Student { // 私有字段 private int _age; // 与_age对应的公开属性,包含了set和get方法 public int Age { get { return _age; } // 利用访问器对输入的年龄进行验证 // 如果输入值小于0或者大于100 // 可以赋为默认值18或者不进行操作 set { if (value >= 0 && value <= 100) _age = value; // 如果数据无效不进行操作可以注释以下内容 else _age = 18; } } } class Program { static void Main(string[] args) { Student stu = new Student(); stu.Age = -2; // 赋无效值 Console.WriteLine(stu.Age.ToString()); Console.ReadKey(); // 输出 18 } } }