【问题标题】:Is there a way to properly parse an enum parameter into a method dynamically invoked有没有办法将枚举参数正确解析为动态调用的方法
【发布时间】:2020-11-06 14:01:51
【问题描述】:

想象以下问题:

//Assembly 1
namespace R {
    public class Remote
    {
        public enum SomeTypes
        {
            A = 12,
            B = 14,
            C = 16
        }
        
        public void DoSomething(SomeTypes s, int a)
        {
            Console.WriteLine((int)s * a);
        }
    }
}

//Assembly 2

namespace L
{
    public class Local
    {
        public enum SomeTypes
        {
            A = 12,
            B = 14,
            C = 16
        }
        
        public Local()
        {
            assembly = ....;
            
            dynamic instance = assembly.DefinedTypes.First(t => t.GetName() == "R.Remote").GetConstructor(Type.EmptyTypes).Invoke(new object [] {});
            
            instance.DoSomething(SomeTypes.A,3); //this is where it crashes because of an argument mismatch, fair point: One is R.Remote.SomeTypes the other one L.Local.SomeTypes
            instance.DoSomething((int)SomeTypes.A,3); //this should work technically, does not, one is R.Remote.SomeTypes the other one int, despite the fact that they can be converted into each other
            instance.DoSomething((dynamic)SomeTypes.A,3); //just a hacky guess, but this does not work either
        }

    }
}

有谁知道如何在不触发参数不匹配异常的情况下调用 DoSomething(...)?

以防万一:我无法访问远程程序集。

提前非常感谢你:)

【问题讨论】:

  • Remote.SomeTypes 是一个 public 枚举,那么为什么要在本地程序集中重新定义它呢?
  • “无法访问远程程序集”是什么意思?您正在从中调用DoSomething(),因此您似乎可以正常访问它。你的意思是你不能修改那个程序集中的代码? Remote 是插件还是什么的?我想知道为什么您要在运行时加载它,而不是仅仅将其添加为参考。现在我也有点困惑。
  • @JohnathanBarclay 导致 OP 有点困惑 =)

标签: c# dynamic reflection


【解决方案1】:

如果你因为某种原因通过反射获取类型,你可以继续使用它来获取所需的枚举值和调用方法:

var remoteType = typeof(Remote); //you remote type from assembly
// you will use var remoteType = assembly.DefinedTypes.First(t => t.GetName() == "R.Remote");
var method = remoteType.GetMethod("DoSomething"); // find needed method somehow
var instance = Activator.CreateInstance(remoteType); // creates instance via parameterless ctor
var remoteSomeType = remoteType.GetNestedType("SomeTypes"); // get Remote.SomeType
var a = remoteSomeType.GetField("A").GetValue(null); // Get Remote.SomeType.A enum value
method.Invoke(instance, new object[]{a, 3}); // call method

请注意,动态/反射通常很慢,因此如果您打算频繁调用此方法,您应该考虑以某种方式“缓存”反射,例如尝试使用 expression trees 编译它。

【讨论】:

  • @slightlyconfused 很高兴它有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-25
  • 1970-01-01
  • 2011-10-01
  • 2020-02-15
  • 2014-11-30
  • 2011-03-17
相关资源
最近更新 更多