私はいつも、this
がインスタンスメソッド本体の中でnullになることは不可能だと考えました。シンプルなプログラムに従えば、それが可能であることを実証します。これは文書化された動作ですか?this == null .NETインスタンスメソッド - なぜ可能ですか?
class Foo
{
public void Bar()
{
Debug.Assert(this == null);
}
}
public static void Test()
{
var action = (Action)Delegate.CreateDelegate(typeof (Action), null, typeof(Foo).GetMethod("Bar"));
action();
}
UPDATE
私はそれがこの方法を文書化されている方法だと言って答えに同意します。しかし、私はこの行動を本当に理解していません。特にC#の設計方法ではないからです。私たちがnullにメソッドを呼び出し 書かれたコードを持っていた誰かからレポートを(おそらくC#を使用して.NETグループ の1()それはまだその時点でのC#の名前が付けられていないと思った)得ていた
ポインタであるが、 は、メソッドがどのフィールドにもアクセスしなかったため(つまり、 「this」はnullだったが、メソッド内で何も使用されていなかったため)例外が発生した。その方法は、 は、この点を使用して の例外を投げた別のメソッドを呼び出し、頭の掻き傷が少し続いた。彼らが を見つけた後、彼らは私たちにそれについてのメモを送った。 ヌルインスタンスのメソッドを呼び出すことができるのは ビットであると思いました。 Peter Goldeは、パーフォーマンスの影響 が常にcallvirtを使用していたことを確認するためにいくつかのテストを行いましたが、それは十分に小さく、 に変更を加えました。
http://blogs.msdn.com/b/ericgu/archive/2008/07/02/why-does-c-always-use-callvirt.aspx
CLRが意図的にこのように.NET 1.0で設計されていることを示す回答を参照してください。あなたが引用している記事は、コンパイラの最適化である別の(デリゲートではない)状況です。インスタンスの型を静的に決定できるときに 'callvirt'を直接呼び出しで置き換えます。 'callvirt'の間にCLRが' NullReferenceException'を投げなければならない理由は、 'this'リファレンスに基づくVMTルックアップの必要性です。参照を確認する意味的な欲求だけではありません。 –
関連:http://stackoverflow.com/q/3143498/158779 –
IMHO、残念なことに、メソッドが 'callvirt'ではなく' call'で呼び出されるようにするための標準的な方法(属性によるもの)はありません。それは値をカプセル化する型[例えば 'string']がデフォルト値の格納場所で動作できるメンバを持つことを許していました。 'if(someString.IsNullOrEmpty)'が 'if(String.IsNullOrEmpty(someString)) 'よりもはるかに洗練されたものになると言ってください。 – supercat