这个LINQ表达式是如何工作的?

5

我知道这段代码在做什么,但是我不确定它的语法是否符合“标准”格式。它似乎主要使用了LINQ?

return db.Subjects.SingleOrDefault(s => s.ID == ID);

第一部分讲得很清楚,但我不理解括号里的部分。我们如何在不声明s的情况下使用它?并且我们如何在方法调用中放置逻辑?

6个回答

17
这里看到的是一个lambda表达式。它是一个非常特殊的匿名委托。 Enumerable.SingleOrDefault 是一个LINQ方法,但lambda表达式与LINQ无关;它们只是使LINQ变得更加友好。
现在,具体来说,IEnumerable<Subject>.SingleOrDefault(s => s.ID == ID) 返回与谓词 s => s.ID == ID 匹配的IEnumerable<Subject>中唯一的Subject实例,如果没有这样的实例,则返回null。如果有多个这样的实例,则抛出异常。在编译时,s => s.ID == ID被转换为一个完整的委托,该委托接受类型为Subject的对象并返回一个布尔值,仅当s.ID等于ID时为true
我们如何在不声明它的情况下使用s? < p > =>lambda运算符。它基本上将lambda表达式的左侧与右侧分开。左侧是输入变量。它相当于显式定义的方法中的参数列表。这里 lambda 表达式中的 s 扮演下面的 s 的角色:

public bool Predicate(Subject s)

这只是因为你不必声明s的类型,编译器会自动推断。

右侧是lambda函数的主体,它等同于下面的主体:

public bool Predicate(Subject s) {
    return s.ID == ID;
}

此外,您不必声明返回类型;编译器会自动推断。因此,最终就好像您执行了以下操作:
class MyPredicate {
    public string ID;
    public bool Predicate(Subject s) {
        return s.ID == this.ID;
    }
}

然后:

// elements is IEnumerable<Subject>
// ID is string
MyPredicate predicate = new MyPredicate();
predicate.ID = ID;
elements.SingleOrDefault(predicate.Predicate);

编译器非常聪明,只要使用lambda表达式,在你不知不觉中就会自动为你生成这个代码块。

很棒的答案!真的是顶级的东西!+1 - Alastair Pitts
@Jason:非常清楚地解释了lambda表达式。不知道您是否可以将其作为一个针对像我这样的初学者的单独问答发布? - balalakshmi

5

这是C# 3.0编译器为您完成了一些魔术。

该语句被编译成一个委托,并且等同于:

return db.Subjects.SingleOrDefault(delegate(s) { return s.ID == ID }); 

因为你不需要正式声明参数,它被称为 lambda 表达式,C# 编译器会自动推断。


5

4
我认为您的困惑在于表达式 s => s.ID== ID。这是一个Lambda表达式,简单来说,它是定义内联函数的一种方式。
在这种情况下,=> 左侧的文本是参数列表。因此,通过它的位置,可以声明s。右侧的部分是要执行的表达式。在这个特定的上下文中,Lambda将在集合中的每个元素上运行,并且代码将断言有一个值满足Lambda执行的表达式。

0

0

s before => 声明一个具有结构元素类型的变量(类型包含在Subjects变量中编辑:其他函数可以使用更多参数,例如Join),该变量位于右侧(=>之后)。逻辑来自函数。如果调用SingleOrDefault(请查阅文档),它将返回满足条件的单个元素或NULL。LINQ中有许多可用的函数(例如First(),Where()等)。希望这有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接