5

次の問題で誰かが私を正しい方向に向けてくれることを願っています。

Reflection.Emit を使用して型が生成されるプロジェクトに取り組んでいます。以下のように Func<> を新しいオブジェクトのコンストラクターに渡す必要があるという要件が発生するまで、すべて正常に機能しています。

public class SearchTerm : IEntity
{
   private readonly NavigationProperty<Item> _item;

   public SearchTerm()
   {
       _item = new NavigationProperty<Item>(() => ItemIds);
   }
   public string[] ItemIds { get; set; }
}

Linqpad を使用すると、IL の出力は次のようになります。

SearchTerm.<.ctor>b__0:
IL_0000:  ldarg.0     
IL_0001:  call        UserQuery+SearchTerm.get_ItemIds
IL_0006:  stloc.0     // CS$1$0000
IL_0007:  br.s        IL_0009
IL_0009:  ldloc.0     // CS$1$0000
IL_000A:  ret         

SearchTerm..ctor:
IL_0000:  ldnull      
IL_0001:  stloc.0     
IL_0002:  ldarg.0     
IL_0003:  call        System.Object..ctor
IL_0008:  nop         
IL_0009:  nop         
IL_000A:  ldarg.0     
IL_000B:  ldloc.0     
IL_000C:  brtrue.s    IL_001D
IL_000E:  ldarg.0     
IL_000F:  ldftn       UserQuery+SearchTerm.<.ctor>b__0
IL_0015:  newobj      System.Func<System.Collections.Generic.IEnumerable<System.String>>..ctor
IL_001A:  stloc.0     
IL_001B:  br.s        IL_001D
IL_001D:  ldloc.0     
IL_001E:  newobj      UserQuery<UserQuery+Item>+NavigationProperty`1..ctor
IL_0023:  stfld       UserQuery+SearchTerm._item
IL_0028:  nop         
IL_0029:  ret  

私が抱えている問題は、IL 内でデリゲートを定義する方法がわからないことです。

私は次のことを試しました

var method = typeBuilder.DefineMethod("func", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual, typeof(IEnumerable<string>), Type.EmptyTypes);

var methodIl = method.GetILGenerator();
methodIl.Emit(OpCodes.Ldarg_0);
methodIl.Emit(OpCodes.Call, dictionary["get_ItemIds"]);
methodIl.Emit(OpCodes.Ret);

次に、デリゲートを作成しようとすると、「派生クラスは実装を提供する必要があります」というエラーとともに「サポートされていない例外」がスローされます。

var funcType = typeof(Func<,>).MakeGenericType(typeBuilder, typeof(IEnumerable<string>));
method.CreateDelegate(funcType);

また、使用する前に型を作成する必要がある Delegate.CreateDelegate と DynamicMethod を使用してみました。

私が間違っているかもしれないことについての提案は大歓迎です。

4

1 に答える 1

2

コードを呼び出したい場合は、Types とMethodInfos ではなく、TypeBuildersと s を操作する必要がありますMethodBuilder

したがって、それとそのメソッドCreateType()を使用する必要があります。Type

var generatedType = typeBuilder.CreateType();

var funcType = typeof(Func<,>).MakeGenericType(
    generatedType, typeof(IEnumerable<string>));
var d = generatedType.GetMethod("func").CreateDelegate(funcType);
于 2013-05-07T14:10:23.500 に答える