【问题标题】:Call dynamic method from string从字符串调用动态方法
【发布时间】:2015-05-17 16:02:10
【问题描述】:

我试图在不知道其名称的情况下从动态调用方法。我很难用英语解释这个,所以有代码:

public void CallMethod(dynamic d, string n)
{
    // Here I want to call the method named n in the dynamic d
}

我想要类似:d.n()n 替换为字符串。

我想要这个:

Type thisType = this.GetType();
MethodInfo theMethod = thisType.GetMethod(TheCommandString);
theMethod.Invoke(this, userParameters);

但具有动态

如果您需要上下文来帮助您:我正在制作一个支持“mods”的应用程序,您将 DLL 放在 mod 文件夹中,然后加载并执行它。它适用于 dynamic(我有一个这样的字典:Dictionnary<string, dynamic> instances;)。我希望应用程序从库中获取方法名称(使用instances["topkek"].GetMethods();,我已经创建了此方法),然后使用它返回的字符串调用该方法。我不知道我说的是不是什么意思(我是法国人:/)...

我正在使用 .Net 框架 4.5 的 VS 2013 Express,如果您需要更多信息来帮助我问我。

【问题讨论】:

  • 如何知道调用哪个方法?您可以在“正常”Type 上使用 Type.GetMethods - 不确定它如何与 dynamic 一起使用。
  • 您的问题过于宽泛,提供的细节很少。请尝试付出一些努力并解释自己。
  • 该方法由用户指定,我想要类似:“d.n()”,ofc 如果该方法不存在它会崩溃。所以这对于动态来说是不可能的?
  • 为什么不通过委托呢?

标签: c# dynamic methods reflection


【解决方案1】:

你可以写你的方法如下 -

public void CallMethod(dynamic d, string n)
    {
        d.GetType().GetMethod(n).Invoke(d, null);
    }

【讨论】:

    【解决方案2】:

    如果所有方法都是无效的,这可能会起作用。否则你需要稍微改变一下。

        public void CallMethod(string className, string methodName)
        {
            object dynamicObject;
            // Here I want to call the method named n in the dynamic d
            string objectClass = "yourNamespace.yourFolder." + className;
            Type objectType = Type.GetType(objectClass);
            if (objectType == null)
            {
                // Handle here unknown dynamic objects
            }
            else
            {
                // Call here the desired method
                dynamicObject = Activator.CreateInstance(objectType);
                System.Reflection.MethodInfo method = objectType.GetMethod(methodName);
                if (method == null)
                {
                    // Handle here unknown method for the known dynamic object
                }
                else
                {
                    object[] parameters = new object[] { };   // No parameters
                    method.Invoke(dynamicObject, parameters);
                }
            }
        }
    

    【讨论】:

    • 谢谢,但我不想创建我的类型的新实例,该实例已经是变量“d”。
    • @SwagLordKnight 那就更简单了,你可以跳过构建objectClass的部分。检查link
    • 能否请您以更具描述性的方式命名您的参数?
    • @AndreasNiedermair 参数是一个对象数组,用来保存要传递给方法的参数。例如,如果该方法需要一个字符串和一个 int,则需要在括号 { } 内添加以下 2 个参数:parameters = new object[] { str, number } 其中 str 和 number 必须在之前的某个地方定义。
    • @AndreasNiedermair 我同意。我应该保持良好的做法,而不是从原始问题中复制名称。谢谢指点;已更新。
    【解决方案3】:

    我想添加另一种方法作为解决方案:

    在您的情况下,调用者(模组的开发者)知道要调用的方法。因此,这可能会有所帮助:

    // In the main application:
    public dynamic PerformMethodCall(dynamic obj, Func<dynamic, dynamic> method)
    {
        return method(obj);
    {
    
    
     // In a mod:
     mainProgram.PerformMethodCall(myDynamicObj, n => n.myDynamicMethod());
    
     // In another mod:
     mainProgram.PerformMethodCall(myDynamicObj, n => n.anotherMethod());
    

    这是 Yuval Itzchakov 在他的评论中的想法的进一步发展。他曾建议使用委托。

    【讨论】:

      猜你喜欢
      • 2021-09-10
      • 2012-04-08
      • 2011-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-23
      • 2013-07-18
      • 2021-11-17
      相关资源
      最近更新 更多