C# 为什么lambda表达式不能使用相同的内部变量?
我是C#的新手,一直在处理这些lambda值 我的问题是,为什么参数列表中的每个变量都不相同?如果你注意到print(q是变量),square(c是变量)和add(x,y)是变量,IsLessThanTen(f是变量),如果我想让它们都有相同的参数名,比如说Pizza,这可以做到吗。那是我在看的教程。我的第二个小问题是,如果您不只是使用常规函数,那么这将如何使代码变得更好 我认为这些被称为Lambda表达式。我在教程视频中听到了几个不同的名字 问题:同一变量能否用于不同的lambda表达式? 我想知道我是否可以在所有lambda表达式中使用变量索引C# 为什么lambda表达式不能使用相同的内部变量?,c#,C#,我是C#的新手,一直在处理这些lambda值 我的问题是,为什么参数列表中的每个变量都不相同?如果你注意到print(q是变量),square(c是变量)和add(x,y)是变量,IsLessThanTen(f是变量),如果我想让它们都有相同的参数名,比如说Pizza,这可以做到吗。那是我在看的教程。我的第二个小问题是,如果您不只是使用常规函数,那么这将如何使代码变得更好 我认为这些被称为Lambda表达式。我在教程视频中听到了几个不同的名字 问题:同一变量能否用于不同的lambda表达式? 我
Action<int> print = index => Console.Writeline(index);
Action print=index=>Console.Writeline(索引);
代码:
Action print=q=>Console.WriteLine(q);
Func square=c=>c*c;
Func add=(x,y)=>x+y;
谓词isLessThanTen=f=>f<10;
印刷品(方形(添加(4,5)));
Console.ReadKey();
是的,lambda参数名可以重用,重复的变量名不会“跨越”同级(又称匿名函数)
导致编译器错误
无法在此作用域中声明名为“q”的局部变量
因为它会给已经使用的“q”赋予不同的含义
在“父或当前”范围中表示其他内容
与普通方法相比,lambda表达式有一些很大的好处:
可以在不同的lambda中使用相同的变量名,但它们在包含它们的方法中必须是唯一的。例如:
void SomeFunction()
{
int i;
Func<int, int> timesTwo = i => i * 2; // Bad. Conflicts with other variable
}
void SomeFunction()
{
int i;
Func times2=i=>i*2;//错误。与其他变量冲突
}
至于你的另一个问题,它们是否比常规方法更好,这完全是主观的,它们都有自己的位置。来回答你的第二个问题。这样使用委托的一个好处是,委托所代表的函数可以在运行时更改 例如,假设您有一个代表
multiply
Func<double, double, double> multiply = (a, b) => a * b;
现在,无论你在哪里使用乘法,它实际上都会除法
在本例中,将multiply
视为一个包含函数的变量,可以作为函数调用。要更改此“变量”的值,必须将其分配给与定义的签名匹配的函数
我过去在一个解决方案中使用多种类型的数据库时使用过委托。根据数据库是Oracle还是MS SQL,委托会有所不同。您可以对所有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;
Action method1=i=>Console.WriteLine(i);
Func method2=i=>i*i;
Func方法3=(i,i2)=>i+i2/i*i*40;
谓词方法4=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();
Action-method1=i=>Console.WriteLine(i+3);
如果(测试==3)
method1=i=>Console.WriteLine(i+i);
否则如果(测试==2)
method1=i=>Console.WriteLine(i+i+i);
Console.ReadKey();
如上所述,method1已在上面定义,但根据测试结果,method1可以更改为其他内容。如果你愿意,你可以用两种不同的方法做同样的事情。我有时不确定人们是否应该使用这种例子。我曾多次在代码中看到过它,但坦率地说,决定何时使用它对我来说似乎很奇怪,因为您可以像上面的示例一样在代码中使用ever函数。我不理解这个问题。您是在问是否可以在单独的lambda表达式中重用相同的变量(当然在同一个闭包之外),还是在同一个表达式中使用它?你能提供一个你认为应该工作但不工作的例子吗?当然,如果每个参数在概念上代表相同的东西,那么使用相同的参数名就可以了。它使用相同的参数名来表示完全不同的东西,这是一个问题。@Servy非常好。我引用了你的评论。根据我的测试,lambda也比函数调用快,我支持,因为它们已经快了delegates@Gusman假与假。lambda不是代理。它们是用于创建委托实例的一种可能语法。lambda将被编译成命名方法,就像任何其他命名方法一样;在编译代码之前,该名称根本不为人所知。您不知道该名称是什么,但该方法在运行时实际上会有一个名称。您的测试在某些方面存在缺陷的可能性非常高;要么你没有比较等价的操作,要么你没有正确地测量它们。这两种方法都很容易做到,因为基准测试很难做到。不,测试了很多次,因为我期望得到oposite结果,调用lambda函数(或函数的委托)更快。我对“are delegate”的意思是,您将从一个委托中使用它(当您将它指定给一个变量,并创建一个委托时),您不能像调用纯函数一样调用它。@Gusman说您已经测试过它,这毫无意义。正如我所说,对代码进行基准测试很难,实际上没有人能正确地进行。你几乎肯定不是在比较你的想法
Func<double, double, double> multiply = (a, b) => a * b;
if(crazyDemandIsMet){
multiply = (a, b) => a / b;
}
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;
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();