2012-12-21 24 views
5

これはReflection.Emitを使用するための最初の試みです。私は動的に提供されたオブジェクトのプロキシを構築しています。プロキシは、publicプロパティへのアクセスを提供されたオブジェクトに渡します。私が受けてるのエラーがある:アクセス方法への方法により、 試み「ProxyObject.get_AccessorName()」 「NS.CoreObject.get_AccessorName:オブジェクト上のReflection.Emitを使用して別のオブジェクトからプロパティ値を取得

プロパティアクセサ「AccessorName」「ProxyObject」は、次の例外をスローした

()に失敗しました。

これは、私が想定して収集できることから、自動的に生成されるプロパティゲッターメソッドがプライベートで非表示になっているためです。しかし、私はMethodBuilderを使用してこれを回避するにはどうすればよいですか?

Create DynamicMethod to assign value to a property?という投稿によると、メソッドをターゲットモジュールに「関連付ける」と宣言することでDynamicMethodで行うことができますが、完全なクラスを構築する必要があります。 Reflection.Emitで達成できる同等の「関連」はありますか?

これは私が実行しようとしている基本的な操作なので、わかりやすい単純なものだと確信しています。

+0

これは、MethodAccessExceptionです。それは、プロパティが実際に公開されていないように確信しています。これをC#で最初に作ってください。それから得られるILは、あなたのemitコードでも非常に役立ちます。 –

+0

もちろん、あなたのクラスが公開されていないときは、公共財産は何も意味しません。私の頭では、このタイプは同じモジュール内で定義されていました。さらに別の* "私はこれで時間を無駄にしましたか?" – redman

答えて

9

MethodBuilderとすることはできません。あなたは通常のアクセシビリティのルールの対象です。しかし、DynamicMethodで不正行為をすることができます。十分なアクセス権を持っていれば、作成するメソッドは実際には特定のタイプ(または特定のモジュールなど)の静的メソッドです。これは、あなたが自由に例えばプライベート状態を、アクセスできることを意味:

あなたがプロパティの値を取得のみしている場合、またDelegate.CreateDelegateはゲッターを経由して、自動的に同じことを行うことに留意すべきである
using System; 
using System.Reflection; 
using System.Reflection.Emit; 

public class Foo 
{ 
    public Foo(int bar) 
    { 
     Bar = bar; 
    } 
    private int Bar { get; set; } 
} 
static class Program { 
    static void Main() 
    { 
     var method = new DynamicMethod("cheat", typeof(int), 
      new[] { typeof(object) }, typeof(Foo), true); 
     var il = method.GetILGenerator(); 
     il.Emit(OpCodes.Ldarg_0); 
     il.Emit(OpCodes.Castclass, typeof(Foo)); 
     il.Emit(OpCodes.Callvirt, typeof(Foo).GetProperty("Bar", 
      BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic 
      ).GetGetMethod(true)); 
     il.Emit(OpCodes.Ret); 
     var func = (Func<object, int>)method.CreateDelegate(
      typeof(Func<object, int>)); 

     var obj = new Foo(123); 
     Console.WriteLine(func(obj)); 
    } 
} 

メソッド:

var method = typeof(Foo).GetProperty("Bar", 
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) 
    .GetGetMethod(true); 
var func = (Func<Foo, int>) 
    Delegate.CreateDelegate(typeof(Func<Foo, int>), method); 
+0

意味があります(創造的です)。 TypeBuilder経由で型を構築している場合は、答えによって生成されたILをTypeBuilder型で取得できますか?または、2つの相互に排他的ですか? – redman

+0

@redmanが同じILを取得しても役に立たないでしょう。 TypeBuilderは*まだ*標準のアクセシビリティに制限されています。 ILレベルでは** **何でも**を求める*ことができます:最初の使用時にはまだチェックされます。 –

+0

私はちょうど私の質問の一部があいまいであることに気づいた。私がアクセスしようとしているプロパティはpublic *です。自動的に生成されるアクセッサではありません。 (私はこれを反映するために私の質問を更新しました。)そのため、MethodBuilderを通して別のオブジェクトのプロパティを使用する方が簡単でしょうか? – redman

関連する問題