为什么不能在lambda表达式中使用ref或out参数?
我今天遇到了这个错误,并找到了一个解决方案,但我仍然好奇为什么这是一个编译时错误。
CS1628:不能在匿名方法、lambda表达式或查询表达式中使用in ref或out参数'parameter'
这里有一个简单的例子:
private void Foo()
{
int value;
Bar(out value);
}
private void Bar(out int value)
{
value = 3;
int[] array = { 1, 2, 3, 4, 5 };
int newValue = array.Where(a => a == value).First();
}
不能在lambda表达式中直接使用out形参。你不能那样做的原因在其他答案中有解释。
解决方案
But you can use a local temporary variable with for the inner function and, after the inner function has been executed, assign the out value from the inner function to the out value of the outer function:
private static int OuterFunc (int i_param1, out int o_param2)
{
int param2 = 0;
var del = () => InnerFunc (i_param1, out param2);
int result = del ();
o_param2 = param2;
return result;
}
private static int InnerFunc (int i_param1, out int o_param2)
{
o_param2 = i_param1;
return i_param1;
}
private static void Main (string[] args)
{
int result = OuterFunc (123, out int param2);
Console.WriteLine (result); // prints '123'
Console.WriteLine (param2); // prints '123'
}
请注意
这个问题创建于2009年。我的答案是在2023年用c# 10和。net 6创建的。我不知道这个答案在2009年是否也适用,这意味着,这里的代码可能依赖于在此期间对c#和。net的增强。
我再举一个例子。
描述
下面的代码将抛出这个错误。因为lambda表达式(i)=>{…}只在函数test中生效。
static void test(out System.Drawing.Image[] bitmaps)
{
int count = 10;
bitmaps = new System.Drawing.Image[count];
Parallel.For(0, count, (i) =>
{
bitmaps[i] = System.Drawing.Image.FromFile("2.bmp");
});
}
解决方案
如果去掉参数,就可以了。
static void test(System.Drawing.Image[] bitmaps)
{
int count = 10;
bitmaps = new System.Drawing.Image[count];
Parallel.For(0, count, (i) =>
{
bitmaps[i] = System.Drawing.Image.FromFile("2.bmp");
});
}
如果真的需要,不要直接更改lambda表达式中的参数。相反,请使用临时变量。
static void test(out System.Drawing.Image[] bitmaps)
{
int count = 10;
System.Drawing.Image[] bitmapsTemp = new System.Drawing.Image[count];
Parallel.For(0, count, (i) =>
{
bitmapsTemp[i] = System.Drawing.Image.FromFile("2.bmp");
});
bitmaps = bitmapsTemp;
}