在C#中如何使用emit调用静态方法

发布于 2024-11-02 19:19:39 字数 860 浏览 1 评论 0 原文

我正在尝试使用 Emit 生成映射代码(将属性从一个对象映射到另一个对象)。如果两种类型匹配(源和目标),我可以让它工作,但我无法让它在类型不匹配的实例中工作,并且我需要在映射中调用静态方法。下面是我认为可行的代码,但我得到一个方法不存在错误,即使它确实存在。我猜我的发出呼叫不正确。有什么建议吗?

foreach (var map in maps)
{
  il.Emit(OpCodes.Ldarg_1);
  il.Emit(OpCodes.Ldarg_0);

  il.EmitCall(OpCodes.Callvirt, map.SourceProperty.GetGetMethod(), null);
  if (map.SourceProperty.PropertyType == map.TargetProperty.PropertyType)
    il.EmitCall(OpCodes.Callvirt, map.TargetProperty.GetSetMethod(), null);
  else if (map.TargetProperty.PropertyType.Name == "ObjectId" && map.SourceProperty.PropertyType.Name.ToLower() == "string") {
    var method = typeof(ObjectId).GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder,  new Type[] { typeof(string) }, null);
    il.EmitCall(OpCodes.Callvirt, method , null);
  }

}
il.Emit(OpCodes.Ret);

I am trying to using Emit to generate mapping code (mapping properties from one object to another). I have it working if the two types match (source and target), but I can't get it to work in an instance where the types don't match and I need to call a static method in the mapping. Below is code that I thought would work but I get a method does not exist error even though it does. I am guessing my emit call is incorrect. Any suggestions?

foreach (var map in maps)
{
  il.Emit(OpCodes.Ldarg_1);
  il.Emit(OpCodes.Ldarg_0);

  il.EmitCall(OpCodes.Callvirt, map.SourceProperty.GetGetMethod(), null);
  if (map.SourceProperty.PropertyType == map.TargetProperty.PropertyType)
    il.EmitCall(OpCodes.Callvirt, map.TargetProperty.GetSetMethod(), null);
  else if (map.TargetProperty.PropertyType.Name == "ObjectId" && map.SourceProperty.PropertyType.Name.ToLower() == "string") {
    var method = typeof(ObjectId).GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder,  new Type[] { typeof(string) }, null);
    il.EmitCall(OpCodes.Callvirt, method , null);
  }

}
il.Emit(OpCodes.Ret);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半枫 2024-11-09 19:19:39

您应该能够通过使用 EmitCallOpCodes.Call 而不是 CallVirt

You should be able to call it by using EmitCall with OpCodes.Call instead of CallVirt.

只涨不跌 2024-11-09 19:19:39

这是引发错误的行吗?

var method = typeof(ObjectId).GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder,  new Type[] { typeof(string) }, null);

也许你可以尝试

Type ObjectIDType = typeof(ObjectId);
MethodInfo method = ObjectIDType.GetMethod("Parse", new Type[] { typeof(string) });

也许 parse 将一个对象而不是字符串作为参数?

错误信息是什么?

This is the line that's throwing the error?

var method = typeof(ObjectId).GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder,  new Type[] { typeof(string) }, null);

Perhaps you could try

Type ObjectIDType = typeof(ObjectId);
MethodInfo method = ObjectIDType.GetMethod("Parse", new Type[] { typeof(string) });

Perhaps parse takes an object as its parameter instead of a string?

What is the error message?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文