为什么我的lambda表达式不能使用相同的内部变量?

时间:2014-04-21 17:00:01

标签: c#

我是C#的新手,正在使用这些lambda值。

我的问题是为什么参数列表不能在每个参数列表中都是相同的变量?如果你注意到print(q是变量)和square(c是变量),而add(x,y)是变量,而IsLessThanTen(f是变量)如果我想让它们都一样参数名称,比如说披萨可以这样做。这是我正在观看的教程。我的第二个小问题是,如果你不仅仅使用常规函数,这将如何使代码变得更好?

我认为这些被称为Lambda表达式。我在教程视频中听到了几个不同的名字。

问题:可以在不同的lambda表达式中使用相同的变量吗?

我想知道我是否可以在所有lambda表达式中使用变量索引

  Action<int> print = index => Console.Writeline(index);

代码:

Action<bool> print = q => Console.WriteLine(q);
Func<double, double> square = c => c * c;
Func<double, double, double> add = (x, y) => x + y;
Predicate<double> isLessThanTen = f => f < 10;

print(isLessThanTen(square(add(4, 5))));

Console.ReadKey();

4 个答案:

答案 0 :(得分:1)

是的,lambda参数名称可以重复使用,重复的变量名称不会与兄弟Lambda Expressions(又名匿名函数)发生冲突。

Action<bool> print = q => Console.WriteLine(q);
Func<double, double> square = q => q * q;
Func<double, double, double> add = (q, q2) => q + q2;
Predicate<double> isLessThanTen = q => q < 10;

..即使它可以导致更难理解代码!正如Servy评论的那样,

  

当然,如果每个参数在概念上代表相同的东西,那么使用相同的参数名称就可以了。 它使用相同的参数名称来表示完全不同的问题。

也就是说,每个lambda中的q单独的变量,即使它们共享相同的名称。


现在,有些情况是不允许的,主要是在外部范围内存在具有相同名称的变量时(在命名共享位于兄弟的问题中)范围)。例如,

int q = 0;
Action<bool> print = q => Console.WriteLine(q);

导致编译器错误

  

无法在此范围内声明名为“q”的局部变量     因为它会给已经使用的'q'赋予不同的含义     在“父母或当前”范围内表示其他内容。


与普通方法相比,lambda表达式有一些很大的好处:

  1. Lambdas表达式可以生成Expression Trees - 这是 背后的魔力。
  2. 与普通方法相比,lambdas可以充当闭包并捕获自由变量。
  3. 甜甜的糖。在LINQ查询中应用上述内容时非常有用。

答案 1 :(得分:1)

您可以在不同的lambda中使用相同的变量名,但它们必须在它们包含的方法中是唯一的。例如:

void SomeFunction()
{
    int i;
    Func<int, int> timesTwo = i => i * 2;  // Bad. Conflicts with other variable
}

关于你的另一个问题,不论他们是否比常规方法更好,这是完全主观的,他们都有自己的位置。

答案 2 :(得分:1)

回答你的第二个问题。使用这样的委托的好处是委托代表的函数可以在运行时更改。

例如,假设您有multiply

的代理人
Func<double, double, double> multiply = (a, b) => a * b;

让我们说,如果满足某个条件,你就需要分裂而不是乘法。

因此...

if(crazyDemandIsMet){
   multiply = (a, b) => a / b;
}

现在,无论你在哪里使用它,它实际上都会分开。

在这种情况下,将multiply视为包含函数的变量,可以作为函数调用。要更改此“变量”的值,必须将其分配给与您定义的签名匹配的函数。

在一个解决方案中使用多种类型的数据库时,我曾使用过代理。根据数据库是Oracle还是MS SQL,代表会有所不同。

答案 3 :(得分:0)

您可以对所有lambda方法使用相同的变量名。

        Action<bool>                 method1 = i => Console.WriteLine(i);
        Func<double, double>         method2 = i => i * i;
        Func<double, double, double> method3 = (i, i2) => i + i2 / i * i *40;
        Predicate<double>            method4 = i => i < 2000;

你不能有一个名为i的局部变量会导致命名转换。人们使用这些类型的表达式的原因是因为它们在某些情况下更快,您可以根据条件动态更改它们

        Action<int>  method1 = i => Console.WriteLine(i + 3);

        if (test == 3)
             method1 = i => Console.WriteLine(i + i);
        else if (test == 2)
             method1 = i => Console.WriteLine(i + i + i);
        Console.ReadKey();

您可以看到上面定义了method1,但根据测试结果,method1可以更改为不同的东西。如果你愿意,你可以用两种不同的方法做同样的事情。我有时不确定应该使用这种类型的例子。我已经在代码中看到了它,但是坦率地说,我决定何时使用它似乎很奇怪,因为你可以像上面的例子一样在你的代码中运行。