その理由は次のとおりです。
ToString
デリゲートを宣言する方法は、静的intインスタンスのメソッドを直接指します。作成時にキャプチャされます。
flindebergが以下のコメントで指摘しているように、各デリゲートにはターゲットとそのターゲットで実行されるメソッドがあります。
この場合、実行されるメソッドは明らかにToString
メソッドです。興味深い部分は、メソッドが実行されるインスタンスです。これはI
、作成時のインスタンスです。つまり、デリゲートはI
インスタンスを使用するために使用していませんが、インスタンス自体への参照を格納します。
後でI
別の値に変更し、基本的に新しいインスタンスを割り当てます。これは、デリゲートにキャプチャされたインスタンスを魔法のように変更しません。なぜそうする必要があるのでしょうか。
期待する結果を得るには、デリゲートを次のように変更する必要があります。
static Func<string> del = new Func<string>(() => I.ToString());
ToString
このように、デリゲートは、デリゲートの実行時に現在で実行される匿名メソッドを指しI
ます。
この場合、実行されるメソッドは、デリゲートが宣言されているクラスで作成された匿名メソッドです。静的メソッドであるため、インスタンスはnullです。
コンパイラがデリゲートの2番目のバージョン用に生成するコードを見てください。
private static Func<string> del = new Func<string>(UserQuery.<.cctor>b__0);
private static string cctor>b__0()
{
return UserQuery.I.ToString();
}
ご覧のとおり、これは何かを行う通常の方法です。ToString
この場合、の現在のインスタンスを呼び出した結果を返しますI
。