2011-07-14 9 views
9

My answer SOの質問の1つは、JITコンパイラでプロパティをインライン展開するとリフレクションが機能しなくなると主張するValentin Kuzubによってコメントされました。次のようにプロパティ/メソッドのインライン化とリフレクションへの影響

場合は、次のとおり

class Foo 
{ 
    public string Bar { get; set; } 

    public void Fuzz<T>(Expression<Func<T>> lambda) 
    { 
    } 
} 

Fuzz(x => x.Bar); 

Fuzz関数は、ラムダ式を受け取り、プロパティを見つけるためにリフレクションを使用します。拡張子がHtmlHelperのMVCではよくあることです。

私は反射が、それがインライン化され、typeof(Foo).GetProperty("Bar")がまだ有効PropertyInfoを返しますBarへの呼び出しであるようBarプロパティは、インライン化されます場合でも、作業を停止することはないと思います。

これを確認してください、または方法のインライン展開が間違っていますか?

+0

Btw INotifyPropertyChangeの実装でlambdaを使用しない理由を示すこの興味深い記事が見つかりました。http://blog.quantumbitdesigns.com/2010/01/26/mvvm-lambda-vs-inotifypropertychanged-vs-dependencyobject/ –

答えて

3

JITコンパイラは実行時に動作し、アセンブリに格納されているメタデータ情報を書き換えることはできません。リフレクションはこのメタデータにアクセスするためにアセンブリを読み取ります。したがって、JITコンパイラからリフレクションへの影響はありません。

編集: 実際には、C#コンパイラ自体がコンパイル時にいくつかの情報を "インライン"するときに、いくつかの場所があります。たとえば、定数、列挙型、およびデフォルトの引数は "インライン"なので、リフレクション中にアクセスすることはできません。しかし、あなたの特定の事件には必ずしも関連しません。

+0

あなたはデフォルトのプロパティを意味しますか? – leppie

+0

私はデフォルトの引数を意味します、申し訳ありません。私は私の答えを編集しました。 –

+0

あなたのリストに 'enums'を追加することができます。 –

0

私は個人的に@Sergeyに同意:

はインライン化がJITコンパイラ側で発生したが、メタデータが前に生成され、それがどのような方法で反射にinpactべきではないと考えます。私はそれについて考えるとき、1

1

うんもっと私はあなたが

public Count 
{ 
get {return m_Count;} 
set { m_Count=value; 
     GetCurrentPropertyNameUsingReflectionAndNotifyItChanged();} 
} 
のように使用する反射ベースの方法を使用していた場合の唯一の方法のインライン化プロパティが正しい仕事のようになりINotifyPropertyChangedのインターフェースを失敗する可能性が推測それのような方法で、良い質問で

メタデータがアセンブリ内に存在し、プロパティ名が実際にそこから取得されることをお勧めします。

私たちはどちらも考えました。

+0

私はまだこの場合でもうまくいくと思います。 –

+0

どのように正確に?メソッドはプロパティからではなく、プロパティを使用しているメソッドから呼び出され、結果の名前はCountではなく、何か異なる(プロパティ名ではなくメソッド名である可能性が高い) –

+0

メソッド「GetCurrentPropertyNameUsingReflectionAndNotifyItChanged' ? –

0

表現木は、表現そのものではなく、表現(抽象構文木)の表現であるため、とにかくインラインにすることはできません。

デリゲートは、たとえインラインであっても、そのプロパティで呼び出されるメソッドとターゲットに関するデータを保持します。

関連する問題