C# 我只能';我似乎不太懂c语言中的Lambdas#
我还没有真正掌握创建和使用lambda表达式。我知道如何在linq语句中使用它们,但我真的不明白幕后发生了什么。我还没有找到一个完整的教程,关于何时使用它们,如何定义它们,等等 第二部分 他们说Javascript是一种LAMBDA语言,我对Javascript相当了解,只是想知道什么类型的概念适用于Javascript lambdas和c#lambdas 第三部分 函数式语言和lambda语言之间有什么区别C# 我只能';我似乎不太懂c语言中的Lambdas#,c#,lambda,C#,Lambda,我还没有真正掌握创建和使用lambda表达式。我知道如何在linq语句中使用它们,但我真的不明白幕后发生了什么。我还没有找到一个完整的教程,关于何时使用它们,如何定义它们,等等 第二部分 他们说Javascript是一种LAMBDA语言,我对Javascript相当了解,只是想知道什么类型的概念适用于Javascript lambdas和c#lambdas 第三部分 函数式语言和lambda语言之间有什么区别 有什么建议吗?这可能会很有用。我不能回答第三部分,但让我在第1和第2部分做一个练习,也
有什么建议吗?这可能会很有用。我不能回答第三部分,但让我在第1和第2部分做一个练习,也许这会对你的第3部分有所帮助 你明白代表的意思吗?因为这就是你要面对的一切。VS2010在这方面非常简洁 在根目录下,lambda只是传递到委托声明中的匿名函数。 或者,更简单地说是不带签名的方法(返回类型、名称和参数)。签名是由用法暗示的 问“何时使用lambda”实际上是问“何时应该为委托使用匿名函数”,实际上,我想不出比LINQ使用它们作为示例的场景更好的场景。明白了,Javascript是一种lambda语言,因为您可以像变量一样传递方法,并使用匿名方法来传递,而不仅仅是声明的方法 至于阅读lambda,我不喜欢一些人使用的“goes to”术语。我倾向于用一种普通的方法来阅读,也就是说: 给定一些参数列表,执行此代码 所以, 行=>行。状态==“NY” 方法 “给定行,当行的状态为纽约时返回true”
也许我过于简单化了,但我是一个简单的人。C#3简而言之,乔恩·斯基特的书在他们的书中很好地解决了这个问题。lambda表达式是一个匿名的一流函数。当您声明一个别名时,您将创建一个可寻址的函数,但可以有任意数量的别名,就像对象一样(因此是第一类)。您可以在变量和参数中传递它。Javascript可以称为lambda语言,因为所有Javascript函数都具有这些属性。它们可以实例化、别名和传递,并且不需要像C do中的函数那样有名称。因此,它们是匿名的一流函数。Lambda本身并不是一种“语言”,而是C语言的一部分。 Lambada表达式是一种“合成糖”,它消除了大量冗余编码 有一个很好的例子说明了lambada提供的快捷方式
还有另一个前/后lambda的例子。我来试试你问题的第一部分。也许值得将第二和第三部分作为单独的问题重新发布 我喜欢将lambdas看作是我定义的函数/过程,类似于局部变量,而不是在模块级别 那么,假设我有以下代码:
public void Run()
{
var template = "{0} inches is {1} centimetres.";
Console.WriteLine(template, 2.0, 2.0 * 2.54);
Console.WriteLine(template, 5.0, 5.0 * 2.54);
}
显然,我不想重复表达式*2.54
,因此我可以定义如下函数:
private double Inches2Centimetres(double inches)
{
return inches * 2.54;
}
我的代码现在变成:
public void Run()
{
var template = "{0} inches is {1} centimetres.";
Console.WriteLine(template, 2.0, Inches2Centimetres(2.0));
Console.WriteLine(template, 5.0, Inches2Centimetres(5.0));
}
但这将函数与调用代码分离,如果这是我唯一需要计算的地方,我实际上会损害代码的可维护性
我可以决定使用lambda,因此我可以编写以下内容:
public void Run()
{
Func<double, double> inches2Centimetres = inches => inches * 2.54;
var template = "{0} inches is {1} centimetres.";
Console.WriteLine(template, 2.0, inches2Centimetres(2.0));
Console.WriteLine(template, 5.0, inches2Centimetres(5.0));
}
在本例中,当我调用函数时,可以传入lamdba,Func transform
,它只需要知道如何将当前行转换为T
类型的对象。所有用于打开连接、执行reader命令、在记录之间移动以及干净地关闭所有内容的代码都由扩展方法处理。我的呼叫代码要简洁得多
string[] names = conn.UsingDataReader<string>("select FirstName from People;",
dr => dr["FirstName"] as string);
string[]names=conn.UsingDataReader(“从人中选择名字;”,
dr=>dr[“FirstName”]作为字符串);
我知道我对你的问题给出了一个非常简单的答案,但我希望它能有所帮助。传统Lambda演算中的函数是一个对单个值进行运算并返回单个值的函数-一元函数。它们也是非常简单的函数,没有做任何特别复杂的事情(通常是将一个集合映射到另一个集合)。要完成复杂的工作,您需要将函数链接起来,以便第一个函数的输出将成为第二个函数的输入 C#中的lambda也是同样的一元函数。我们使用它们来投影、转换、过滤或排序数据
将“Lambda”想象成一个接受参数并返回值的函数。我可以处理JavaScript部分。因为您可以在JS(
var fn=function(){/*stuff*/};
)中声明匿名函数,所以您还可以将这些函数作为参数传递给其他函数。事实上,如果您必须执行自定义排序例程,您已经使用了lambdas。例如:
// Standard sort:
x = [4,3,6,7,1,5,2];
x.sort();
// Custom sort:
y = [
{'val':4,'name':'four'},
{'val':3,'name':'three'},
{'val':6,'name':'six'},
{'val':7,'name':'seven'},
{'val':1,'name':'one'},
{'val':5,'name':'five'},
{'val':2,'name':'two'},
];
y.sort(function(a,b){ return a.val > b.val ? 1 : -1 });
replace()
是将lambda函数作为参数的另一个示例
在您自己的代码中执行此操作非常容易,尽管在实践中,我从未发现有一种情况无法以其他方式更清楚地执行此操作(如果其他任何人需要管理您的代码,在他们看到lambda之前,您一定会打断他们的头)
下面是一个示例。假设您有一个生成某种形式输出的小部件
对象。您知道它将始终生成输出,但您不知道该输出将采用何种形式。一个解决方案是将生成该输出所需的方法传递给对象。下面是一个简单的实现:
var wWidget = new Widget();
wWidget.publicVar = "I have overridden the public property";
var strSummary = wWidget.publish(fnSummary);
var strDetails = wWidget.publish(fnDetails);
console.log(strSummary,strDetails);
首先,Widget
本身。请注意,Widget.prototype.publish()
接受一个参数,它是您的自定义格式化程序:
var Widget = function() {
var self = this;
var strPrivateVar = "This is a private variable";
self.publicVar = "This is a default public variable";
self.publish = function(f) {
var fnFormatter = f;
var strOutput = "The output is " + fnFormatter(self,strPrivateVar);
return strOutput;
}
};
接下来是格式化程序。一个提供简要摘要,另一个提供全文:
var fnSummary = function(o,s) {
var self = o;
var strPrivateVar = s;
return strPrivateVar.substr(0,5) + ' ' + self.publicVar.substr(0,5);
}
var fnDetails = function(o,s) {
var self = o;
var strPrivateVar = s;
return strPrivateVar + ' ' + self.publicVar;
}
最后,你的工具
var wWidget = new Widget();
wWidget.publicVar = "I have overridden the public property";
var strSummary = wWidget.publish(fnSummary);
var strDetails = wWidget.publish(fnDetails);
console.log(strSummary,strDetails);
delegate int D(int x);
...
class C
{
void M(int y)
{
int z = 123;
D d = x=>x+y+z;
Console.WriteLine(d(10));
z = 345;
y = 789;
Console.WriteLine(d(10));
}
}
delegate int D(int x);
...
class C
{
private class Locals
{
public int y;
public int z;
public int A(int x)
{
return x + this.y + this.z;
}
}
void M(int y)
{
// Initialize the closure class:
Locals locals = new Locals();
locals.y = y;
// Transform the body so that all usages of y, z and the lambda
// refer to the closure class:
locals.z = 123;
D d = locals.A;
Console.WriteLine(d(10)); // Calls locals.A(10)
locals.z = 345;
locals.y = 789;
Console.WriteLine(d(10)); // Calls locals.A(10)
}
}