那么,在我所有复杂的公式代码中,我忽略了C#的基本原理。
方法可能会返回一个值。
static dynamic Construct<T>(T expression){
return expression;
}
然后只使用它,而不是变量......
Method = Construct<Action<Context, string, int>>(
(context, key, change) =>
{
context.Saved[key] += change;
Console.WriteLine("{0}'s saved value of {1} was changed by {2}, resulting in {3}",
context.Name, key, change, context.Saved[key]);
}
)
我有一种情况需要调用不存在的编译方法,而是需要能够接受参数数组并作为匿名函数执行。我以为我已经解决了问题,但我遇到了以下问题..
public static IDictionary<string, Function> Expressions =
new Dictionary<string, Function> {
{
"Increase [X] by value of [Y]",
new Function {
Name = "Increase [X] by [Y]",
Parameters = 2,
Types = new List<Type>{
typeof(Param),
typeof(Param)
},
Method = (Expression<Func<Context, Param, Param, bool>>)
((context, x, y) => {
Console.WriteLine("test"); // this is where I need to do stuff...
})
}
}
};
我被告知Method name is expected
就此而言。问题是Context
将由接受该函数并运行其方法的对象传入,因为Context
对象不能预先绑定(它必须是后期绑定的)。所以基本上我在这种情况下打包了尾随的2个参数(Param
)和(Param
)并创建了一个对它们执行的函数。
数据库存储这些参数,然后使用Context
调用传入相应Compile().DynamicInvoke(object[] params)
作为第一个参数的方法。
有人可以帮我解释为什么我不能在{ }
之间加入任何逻辑吗?
好的,既然我被告知这个例子还不清楚,这里有一个完整的程序从头到尾完成,说明我想要完成的任务。
public class Program {
static void Main(string[] args) {
// simple object stored in database.
var ctx = new Context {
Name = "Ciel",
Saved = new Dictionary<string, int> {
{ "First", 10 },
{ "Second", 20 }
}
};
// simple object stored in database.
var rule = new Rule {
Equations = new List<Equation> {
new Equation {
Parameters = new List<object>{
"First",
5
},
Name = "Increase [X] by value of [Y]"
}
}
};
// =======================================
// runtime environment!!!
// =======================================
var method = Evaluations.Expressions[rule.Equations[0].Name].Method;
var parameters = rule.Equations[0].Parameters;
// insert the specific context as the first parameter.
parameters.Insert(0, ctx);
method.DynamicInvoke(parameters.ToArray());
Console.ReadLine();
}
}
public class Function {
public string Name { get; set; }
public dynamic Method { get; set; }
}
public class Equation {
public string Name { get; set; }
// these objects will be simple enough to serialize.
public IList<object> Parameters { get; set; }
public Function Function { get; set; }
}
public class Context {
public string Name { get; set; }
// this is a crude example, but it serves the demonstration purposes.
public IDictionary<string, int> Saved { get; set; }
}
public class Rule {
// again, a crude example.
public IList<Equation> Equations { get; set; }
}
public static class Evaluations {
static Action<Context, string, int> expr = (context, key, change) =>
{
context.Saved[key] += change;
Console.WriteLine("{0}'s saved value of {1} was changed by {2}, resulting in {3}",
context.Name, key, change, context.Saved[key]);
};
public static IDictionary<string, Function> Expressions =
new Dictionary<string, Function> {
{
"Increase [X] by value of [Y]",
new Function {
Name = "Increase [X] by [Y]",
Method = expr
}
}
};
}
答案 0 :(得分:2)
四个问题:
Expression<Func<Context, Param, Param, bool>>
称为具有bool
参数的方法。你在那里尝试做什么并不清楚。答案 1 :(得分:1)
如果您重构代码以使其更具可读性和可管理性,那么您可能会很好地解决问题。而不是使用单个分号的一个庞大的C#语句,将其分成几行。像这样:
public static Dictionary<string, Function> Expressions = getExpressions();
private static Dictionary<string, Function> getExpressions()
{
var method = (Expression<Func<Context, Param, Param, bool>>)
((context, x, y) => {
Console.WriteLine("test"); // this is where I need to do stuff...
})(true);
var func = new Function()
{
Name = "Increase [X] by [Y]",
Parameters = 2,
Types = new List<Type>
{
typeof(Param),
typeof(Param)
},
Method = method
};
var dict = new Dictionary<string, Function>();
dict["Increase [X] by value of [Y]"] = func;
return dict;
}
注意:我的语法可能不正确,但您可以得到一般的想法。