C# 我只能';我似乎不太懂c语言中的Lambdas#

C# 我只能';我似乎不太懂c语言中的Lambdas#,c#,lambda,C#,Lambda,我还没有真正掌握创建和使用lambda表达式。我知道如何在linq语句中使用它们,但我真的不明白幕后发生了什么。我还没有找到一个完整的教程,关于何时使用它们,如何定义它们,等等 第二部分 他们说Javascript是一种LAMBDA语言,我对Javascript相当了解,只是想知道什么类型的概念适用于Javascript lambdas和c#lambdas 第三部分 函数式语言和lambda语言之间有什么区别 有什么建议吗?这可能会很有用。我不能回答第三部分,但让我在第1和第2部分做一个练习,也

我还没有真正掌握创建和使用lambda表达式。我知道如何在linq语句中使用它们,但我真的不明白幕后发生了什么。我还没有找到一个完整的教程,关于何时使用它们,如何定义它们,等等

第二部分

他们说Javascript是一种LAMBDA语言,我对Javascript相当了解,只是想知道什么类型的概念适用于Javascript lambdas和c#lambdas

第三部分

函数式语言和lambda语言之间有什么区别


有什么建议吗?

这可能会很有用。

我不能回答第三部分,但让我在第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)

    }
}