thisアクセス
実行中のインスタンスを指す
メソッドやコンストラクタ、またはプロパティなど、クラス内のコードはメンバアクセス演算子を用いることなく、識別子だけで自分自身の別のメンバを呼び出すことができました。これは、メソッド内のコードがメソッドの呼び出しに用いられたオブジェクト(インスタンス)に関連付けられているため、暗黙的に自分自身を表すインスタンスを通じてメンバにアクセスできるからです。
これまで作成したようなメソッド、コンストラクタ、プロパティといったメンバのブロックに含まれているコードには、メンバを呼び出したインスタンスを格納する this という特別な値を持ちます。this は C# の使用で定められているキーワードであり、常に現在のコードを実行してるインスタンスの型となります。この this キーワードを用いた自分自身を実行しているインスタンスへのアクセスを this アクセス(this access)と呼びます。
this
this は自分自身のインスタンスを指すオブジェクトとして、式の中で利用できます。自分自身のクラスの他のメンバを、メンバアクセス演算子を用いて明示的にアクセスしたい場合に用いられます。
class MagicalGirl { private string nameField; public string Name { get { return this.nameField; } } public MagicalGirl(string name) { this.nameField = name; } } class Test { public static void Main(string[] args) { MagicalGirl nanoha = new MagicalGirl("高町なのは"); System.Console.WriteLine("Name=" + nanoha.Name); } }
コード1は、何の変哲もない Name プロパティとコンストラクタを持つ MagicalGirl クラスを作成しています。この中のコードが、自分のメンバにアクセスするために this キーワードを用いている点に注目してください。これまでのように this を省略してメンバ名だけでアクセスすることに何の問題もありませんが、この実行結果から this キーワードが自身のインスタンスを指す値であることが確認できます。
単にメンバにアクセスするのであれば this アクセスを使用する必要はありませんが、メンバ名とローカルの識別子が衝突したときに役に立ちます。多くは、フィールド名とローカル変数の名前が同じ場合に応用されます。メソッドやコンストラクタのパラメータ名をフィールド名に一致させるという命名は珍しいものではありません。
class A { private int x; public A(int x) { x = x; //??? } }
上のコードの A クラスのコンストラクタは x フィールドに x パラメータの値を代入しようとしています。しかし、x フィールドと x パラメータの名前が同じであるため、このままでは代入できません。A() コンストラクタ内で x という識別子は、ローカル変数である x パラメータが優先されます。
そこで x という識別子が x フィールド(メンバ)であることを明示的に記述するために this アクセスを用います。
class A { private int x; public A(int x) { this.x = x; //OK } }
this は自分自身のインスタンスを表す値であるため、this を用いて x フィールドへのメンバアクセスを明示的に記述できます。
class MagicalGirl { private string name; public string Name { get { return name; } } public MagicalGirl(string name) { this.name = name; } } class Test { public static void Main(string[] args) { MagicalGirl nanoha = new MagicalGirl("高町なのは"); System.Console.WriteLine("Name=" + nanoha.Name); } }
コード2の実行結果はコード1と同じですがフィールド名が変更されています。name フィールドとコンストラクタの name パラメータが同じ名前なので、コンストラクタ内で name フィールドに name パラメータを代入するために this アクセスを用いています。