我想知道您是否可以从现有委托创建和修改表达式树。
有点像
public void Foo() {
Console.WriteLine(1000);
}
....
Expression exp = Foo.GetExpression();
//Now do something what changes 1000 to 2000...
所以我想对已经完全排除的方法进行逆向工程。
我的问题是我有这样的结构:
var acts = new Action[20];
for (int i = 0; i != 20; i++)
acts[i] = () => { Console.WriteLine(i); };
并且通过C#的工作方式,所有行为都是相同的(打印20)。但我想要那个
acts[5]()
打印5
acts[11]()
打印11,依此类推。
所以我需要计算20个不同的代表,我想知道这是一个“好”的方法。我当然可以写:
acts[0] = () => Console.WriteLine(0);
acts[1] = () => Console.WriteLine(1);
acts[2] = () => Console.WriteLine(2);
acts[3] = () => Console.WriteLine(3);
....
但这不是我眼中的好方法......
答案 0 :(得分:3)
Anton的解决方案几乎正确,但他正在错误的时间复制变量。你想要这个:
for (int i = 0; i != 20; i++)
{
int tmp = i;
acts[i] = () => Console.WriteLine(tmp);
}
这样捕获的变量是tmp
而不是i
- 而且只有一个i
变量,其值在每次迭代时都会发生变化,每次迭代都有一个“新的”tmp
变量。
有关详情,请参阅Eric Lippert关于该主题的博文(part 1,part 2)。
(要根据标题回答原始问题 - 您无法在此处以有用的方式从委托创建表达式树 - 您可以创建的唯一表达式树是仅调用原始委托的表达式树。)
答案 1 :(得分:2)
像这样改写:
for(int i = 0; i != 20; i++)
{
var x = i;
acts[i] = () => { Console.WriteLine(x); };
}