【问题标题】:Invoking Method with parameters使用参数调用方法
【发布时间】:2017-08-31 17:37:04
【问题描述】:

我正在用我自己的函数编写一个非常简单的脚本工具。

无论有无参数,我都可以很好地调用方法。我的主要问题是解析用户输入的参数。 我需要自己硬核解析器还是有更好的方法?

示例代码

 public class FunctionList
    {
        public void MyMethod(string x)
        {
            MessageBox.Show(x);
        }
    }

    public void Test()
    {            
        Type type = typeof(FunctionList);
        MethodInfo method = type.GetMethod(debugBox.Text);
        FunctionList c = new FunctionList();
        method.Invoke(c, new object[] { "lorem ipsum" });
    }

TextBox 中的用户输入示例:

MyMethod(Hello World)
Sleep(500)
MyMethod(Waited 500 ms)
Sum(5, 4)

我还想添加条件和循环,但我认为这需要调用方法以外的东西。

我想出的解析器示例:

        public void Test()
    {            
        Type type = typeof(FunctionList);
        MethodInfo method = type.GetMethod(helper.GetUntilOrEmpty(debugBox.Text, "(")); //gets all text until first ( which translates to the function name
        FunctionList c = new FunctionList();
        //Handles one argument, gets the text between ( )
        int pFrom = debugBox.Text.IndexOf("(") + "(".Length;
        int pTo = debugBox.Text.LastIndexOf(")");
        string result = debugBox.Text.Substring(pFrom, pTo - pFrom);               
        //pass params        
        method.Invoke(c, new object[] { result });
    }

【问题讨论】:

  • 它被称为Roslyn
  • 当你需要解析时,你需要一个解析器。如果我不想使用 Roslyn,我会使用 NCalc。您可以轻松地使其调用您提供的 .NET 方法。但是在谷歌上搜索“.net expression evaluator”会发现很多选择,其中大多数至少物有所值。
  • @你的编辑:你有你的脚本语言的规范吗?带有双引号作为分隔符的字符串和可能的分隔符转义序列是您需要解析的唯一类型的参数吗?或者你可以只使用 C#,那么有很多动态代码执行选项,可以调用主机程序集。我曾经用 ANTLR 做过一次,但现在没有必要了,我们可以使用几个开源脚本引擎。
  • @dlatikay 我只会处理字符串和int,函数最多需要3个参数
  • 你可以用一个简单的解析器来做到这一点。但并非没有。如果您只是将其作为概念验证或学习或娱乐,请考虑您可以在字符串文字中使用括号和逗号,而无需为参数列表使用简单的String.Split。可能你也不能没有在字符串中转义引号的语法。这很快就会变得复杂。

标签: c# invoke


【解决方案1】:

我在处理此类情况方面拥有丰富的经验。我开发了自己的脚本引擎(回到 Adob​​e Flash 的黄金时代)。

如果您有一个复杂的机制来创建函数和对象,那么我建议您编写一个解析器,将您的自定义脚本代码转换为 C# 的编译时无错误代码。

我已经测试了您的代码,如果您已经知道要传递哪个参数,它就可以正常工作。

   public void Test()
    {
        Type type = typeof(FunctionList);
        MethodInfo method = type.GetMethod("MyMethod");
        FunctionList c = new FunctionList();
        // if you dont know the type of parameter passed then you have to write a parser to determine the type of the parameter right before executing the method. 

        method.Invoke(c, new object[] { "lorem ipsum" , 10});
    }

}

public class FunctionList
{
    public void MyMethod(string x, int y)
    {
        MessageBox.Show(x + " : " + y);
    }
}

【讨论】:

  • 所以你说我唯一的选择是编写自己的自定义解析器?我将编辑一个我想出的例子
  • 在我说是之前...您能提供更多信息吗?就像来自您的自定义语言的示例代码,然后您究竟在 C# 中尝试什么来运行生成的代码?我 100% 确定我以前做过这样的事情。如果您告诉我您的确切代码/需求,我可以分享我的经验。 ;)
  • 非常简单,我创建自己的函数,然后调用,每个函数最多有 3 个参数,用户通过在文本框中键入函数来调用函数(多行),我将编辑我的主要帖子,以便您更好地理解,我可能还想添加设置变量并稍后使用它们的可能性,但我怀疑简单的调用方法+解析不会削减它。注意我的编辑:)
  • @Dimakossover,刚刚看到你的代码。它不会工作。我很快就会给你一个完整的答案。我有同样的情况,我花了很多天来寻找如何做到这一点。我编写了自己的语言,它的解析器生成编译时无错误的 C# 代码,然后将该代码编译成 C# 并调用它。尽管您的情况不同,因为您只希望他们通过参数传递要调用的功能。有时间我会给你买点东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-23
  • 2013-05-05
  • 2018-06-03
  • 2023-03-07
  • 1970-01-01
相关资源
最近更新 更多