为什么你不能使用lambda表达式ref或out参数?
我今天整个的错误来了,找到了解决方法,但我仍然好奇,为什么这是一个编译时错误。
CS1628 :不能匿名方法,lambda表达式,或查询表达式内侧ref或out参数“参数”使用
这里有一个简单的例子:
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表达式有改变,他们捕捉变量寿命的外观。 例如以下lambda表达式引起的参数P1 寿命比当前方法帧作为它的值可以在方法帧之后访问是不再在堆栈上
Func<int> Example(int p1) {
return () => p1;
}
捕获的变量的另一特性是,改变所述可变也是lambda表达式外部可见。 例如,下面的打印42
void Example2(int p1) {
Action del = () => { p1 = 42; }
del();
Console.WriteLine(p1);
}
这两个属性产生一组特定的效果,其在飞行ref参数的面以下列方式
- ref参数可具有固定的寿命。 考虑通过一个局部变量作为ref参数的函数。
- 在lambda副作用将需要对裁判参数本身可见。 两个方法中,并在调用者。
这些是有些不兼容的特性,是他们在lambda表达式不允许的原因之一。
引擎盖下,匿名方法是通过提升捕获变量 (这是你的问题的身体是关于什么的),并存储为编译器生成的类的字段来实现。 有没有方法来存储一个ref
或out
参数作为一个字段。 埃里克利珀在讨论其博客条目 。 注意,这里捕获的变量和参数拉姆达之间的差异。 你可以有“形参”之类的下面,因为它们不是捕获变量:
delegate void TestDelegate (out int x);
static void Main(string[] args)
{
TestDelegate testDel = (out int x) => { x = 10; };
int p;
testDel(out p);
Console.WriteLine(p);
}
你可以,但你必须明确地定义所有的类型,因此
(a, b, c, ref d) => {...}
是无效的,但是
(int a, int b, int c, ref int d) => {...}
已验证
由于这是“C#拉姆达参考”在谷歌上的结果之一; 我觉得我需要在上述答案扩大。 年长的(C#2.0)匿名委托的语法著作和它支持更复杂的签名(以及关闭)。 LAMBDA的和至少是匿名的代表分享了知觉实现在编译器后端(如果它们不相同) - 最重要的是,他们支持闭包。
我试图做的时候我做了搜索,展示的语法:
public static ScanOperation<TToken> CreateScanOperation(
PrattTokenDefinition<TNode, TToken, TParser, TSelf> tokenDefinition)
{
var oldScanOperation = tokenDefinition.ScanOperation; // Closures still work.
return delegate(string text, ref int position, ref PositionInformation currentPosition)
{
var token = oldScanOperation(text, ref position, ref currentPosition);
if (token == null)
return null;
if (tokenDefinition.LeftDenotation != null)
token._led = tokenDefinition.LeftDenotation(token);
if (tokenDefinition.NullDenotation != null)
token._nud = tokenDefinition.NullDenotation(token);
token.Identifier = tokenDefinition.Identifier;
token.LeftBindingPower = tokenDefinition.LeftBindingPower;
token.OnInitialize();
return token;
};
}
只要记住,lambda表达式是程序上和数学上更安全(因为前面提到的参考价值提升的):你可能会打开一罐蠕虫。 使用此语法时,应仔细考虑。