c# - 使用将 Func<> 作为参数传递的 Reflection Emit 创建构造函数调用

标签 c# reflection delegates reflection.emit

我希望有人能为我指明正确的方向,解决以下问题。

我正在开发一个使用 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 中定义委托(delegate)。

我试过以下方法

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);

然后尝试创建委托(delegate)时抛出“不支持的异常”和错误“派生类必须提供实现。”

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

我也尝试过使用 Delegate.CreateDelegate 和 DynamicMethod,它们都需要在使用它们之前创建类型。

非常感谢任何关于我可能做错的建议。

最佳答案

如果你想调用你的代码,你必须使用 TypeMethodInfo,而不是 TypeBuilder MethodBuilders.

因此,您需要 CreateType() 然后使用该 Type 及其方法:

var generatedType = typeBuilder.CreateType();

var funcType = typeof(Func<,>).MakeGenericType(
    generatedType, typeof(IEnumerable<string>));
var d = generatedType.GetMethod("func").CreateDelegate(funcType);

关于c# - 使用将 Func<> 作为参数传递的 Reflection Emit 创建构造函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16418904/

相关文章:

c# - EF Core 2.1 查询 - 左连接

c# - 从 C# 代码执行 IronPython 脚本

c# - 如何在 C# 和 MongoDB 版本 ="2.2.3"中向 IMongoCollection 动态添加过滤器?

c# - 在泛型集合中使用类型变量

c# - 我可以设置一个带有运行时变量的 Func<> 函数来忽略将它们作为 C# 中的参数传递吗?

c# - 遇到 MySQL 异常问题

c# - 为什么我不能更改 String.Empty 的值?

java - getClass() 返回 java.lang.Class [反射(reflection)]

ios - swift 采用的 objective-c 协议(protocol)

C# 通过 Delegate.CreateDelegate 使用具有值类型的属性