我的服务有很多不同的方法,有很多参数。我已经创建了一个服务客户端,但是为所有可能的参数和函数创建UI会非常麻烦,所以每个方法只有一个按钮,代码会配置所有参数。它运行良好,但每次需要其他参数时,都必须更改代码。所以我想如果我的文本框中包含的代码将被动态编译和调用,这将非常方便使用。所以我想要的是我有一个文本框,其代码类似ExecuteOperation1("a", "b", "c")
,其中ExecuteOperation在我的表单类中定义。然后我可以轻松地动态更改参数。我试图搜索它是如何完成的,但所有示例都显示了使用命名空间和类等进行编译。有没有办法以某种方式在你的类中运行动态代码。我的问题的另一个简单的解决方案当然也很受欢迎。
答案 0 :(得分:3)
有几种不同的方式可以动态运行代码。一个不错的方法是使用Microsoft提供的文件dynamic.cs available here(在LinqSamples \ DynamicQuery \ DynamicQuery下)。使用的一个例子是here。
您还可以根据this article on MSDN自行手动构建表达式树。但是你需要编写一些解析代码才能做到这一点。
我已经使用了上述两种方法,我认为第一种方法对于您想要解决的问题似乎最有希望。例如,您可以将一些任意对象o
作为表达式的参数,并包含其他对象,例如settings
,这样用户就可以像在测试中一样编写o.ExecuteOperation1("a", "b", "c", settings)
以下计划。
using System.Linq.Expressions;
using System.Linq.Dynamic;
// ...
public class Settings
{
public int x;
}
public class Window
{
public object ExecuteOperation1(string a, string b, string c, Settings s)
{
Console.WriteLine("{0}, {1}, {2}, {3}", a, b, c, s.x);
return true;
}
}
class Program
{
static void Main(string[] args)
{
string strExpr = "o.ExecuteOperation1(\"a\", \"b\", \"c\", settings)";
Window form = new Window();
Settings s = new Settings();
s.x = 42;
Type retType = typeof(object);
ParameterExpression[] paramExprs = new ParameterExpression[] {
Expression.Parameter(typeof(Window), "o"),
Expression.Parameter(typeof(Settings), "settings") };
LambdaExpression Le = System.Linq.Dynamic.DynamicExpression.ParseLambda(
paramExprs, retType, strExpr);
Delegate compiledLe = Le.Compile();
object result = compiledLe.DynamicInvoke(form, s);
Console.WriteLine("Result is {0}", result.ToString());
}
}
该程序输出
a, b, c, 42
Result is True
我必须在Dynamic.cs中注释掉第1137到1138行以使其工作(这些行排除了使用用户定义类型Window
)。
最后,有Roslyn,它使.net编译器可用作服务。我自己没有使用它,因为它是在技术预览中,我想要一些我现在可以部署的东西。然而,似乎有很多例子,有些是针对那种你想要的东西。
答案 1 :(得分:0)
如果它总是看起来像ExecuteOperation1("a", "b", "c")
那么您可以使用反射来确定方法和参数名称。例如,下面的代码为您提供了一个方法列表。 MethodInfo.Invoke可用于调用方法。
typeof(Service).GetMethods(BindingFlags.Public|BindingFlags.Instance);
这种方法不是很灵活,但相对容易理解,不需要额外的库。