在c#中,意思是=>标志

时间:2012-12-01 09:23:58

标签: c# lambda

有一个名为Student的类,其属性为IdNamePhone。 在UI表单中,以下列方式列出了Student

List<Student> students=new List<Student>();

最后有dataGridview_Cellclick事件的代码,其中使用了以下代码:

string id = dataGridview.Rows[e.RownIndex].Cells[0].Value.ToString();  
Student aStudent = students.Find(i=> i.Id== id);

students.Find(i=> i.Id== id)做了什么?这是什么意思? =>符号的含义是什么?它是如何工作的?

6 个答案:

答案 0 :(得分:4)

它们称为Lambda表达式...... Lambda表达式使用特殊语法。它们允许将函数用作变量或字段等数据。 lambda表达式语法使用=&gt;运营商。这将分隔匿名函数的参数和语句体。

你可以将其作为&#34;转到&#34;。

=&gt;运算符可以读作&#34;转到&#34;并且在声明lambda表达式时始终使用它。 lambda表达式允许您将带有可执行语句的函数用作参数,变量或字段。

请参阅MSDN上的this link以更好地了解它。

答案 1 :(得分:3)

这是goes to运算符(或lambda operator),它在lambda expressions(匿名方法创建)中用于将输入变量与lambda主体分开。

在您的示例中students.Find(i => i.Id== id)输入变量i转到lambda body i.Id == id(即作为匿名方法参数传递)。


另请查看您正在使用的List<T>.Find方法。它接受T类型的predicate,在您的情况下为Predicate<Student>。 Predicated是一个委托,它表示定义一组条件并确定指定对象是否满足这些条件的方法。它有以下签名:

public delegate bool Predicate<in Student>(Student obj)

因此,您需要传递一个方法,该方法接受一个学生对象并返回一个bool。您可以为此创建常规命名方法:

private bool IsStudentHasIdEqualTo5(Student s)
{
   return s.Id == 5;
}

并以这种方式使用它:

Student aStudent = students.Find(IsStudentHasIdEqualTo5);

但您需要验证不同的id值。有两个选项 - 在您的类中创建字段,这将在学生谓词方法中可用,或创建类,它将同时包含此方法和字段:

class StudentSearcher
{
    private int _id; // capture id

    public StudentSearcher(int id)
    {
        _id = id;
    }

    // method has same signature as bool Predicate(Student obj)
    public bool VerfyId(Student s)
    {
        return s.Id == _id;
    }
}

现在,您可以使用此命名方法,并为学生验证提供不同的id值:

var searcher = new StudentSearcher(id);
Student aStudent = students.Find(searcher.VerfyId);

但是为每次搜索创建这样的方法和类并不是很有效。这就是为什么我们有代表(和lambdas)。您可以在您需要的地方创建没有名称(匿名)的方法,而不是声明新的命名方法,编译器将为您生成通常的命名方法:

Student aStudent = students.Find(delegate(Student s) { 
                                      return s.Id == id; 
                                 });

完全相同的代码可以用lambda语法编写(委托关键字省略,参数类型推断,goes to运算符用于分隔参数和方法体,return关键字也省略):

Student aStudent = students.Find(s => s.Id == id);

这里的神奇之处在于编译器将生成如上所示的类似于场景的类。该类将具有带谓词签名的方法,并且还将具有用于捕获id以进行搜索的字段。

答案 2 :(得分:1)

=&gt; goesto 运算符,此表达式为 lambda expresion

请参阅msdn

答案 3 :(得分:1)

lambda运算符将函数参数与其主体分开。

(arg1,arg2...argn)
=>
{
  //body
}

身体也可能没有括号..但它仍然是一个“身体”。

(arg1,arg2..argn) => 1 ;

Student aStudent = students.Find(i=> i.Id== id);

Find是一个采用lambda表达式的Linq方法。

它将贯穿学生的每个元素。

元素由i表示 - 虽然student会更有意义 - 并且会被传递到“正文”中。 如果i.Id==id,则Find方法会返回student元素。

答案 4 :(得分:1)

  • students.Find(i=> i.Id== id)做什么?

情况就是这样。您有一个学生对象列表和您感兴趣的学生的ID。如果学生对象存储在一个集合中,您自己定义了一个带有ID的Find方法并返回具有该id的学生,您的代码看起来像这样:

Student aStudent = students.Find(id);

然而,当微软定义了通用的List集合时,他们不可能知道如何使用它 - 而且他们不想知道。他们希望让您有机会将它与Student对象或您能想到的任何其他类型一起使用。但这意味着他们必须通过提供只有您知道的问题信息,为您提供一种方法来找到您所追求的元素。在这个特定的实例中,您知道您正在寻找存储在学生列表中的Student对象,该对象的Id字段与您拥有的ID相匹配。如果我给你一个对象,让我们称之为i,你可以通过执行以下检查告诉我它是否是你要找的对象:

i.Id == id 

如果我给你一个名为student的对象,你就可以执行测试student,你可以通过执行测试告诉我你是否是你所追求的那个

student.Id == id

(如果您没有id,但是其他一些信息唯一地确定了Student对象(即一个键),那么您需要指定一个不同的条件。灵活性非常重要!)

所以,现在我们到达下一个问题。

  • 这是什么意思?

    让我们创建一个约定。您将确定要将学生对象称为什么,然后您将提供一个适当的检查来挑选您所学的学生。您将代表该学生的标识符放在=>的左侧,并将检查条件放在右侧。因此,你可以有类似的东西:

    student =&gt; student.Id == id

或者如果您希望引用正在讨论的学生对象i而不是student,那么您可以写

i =&gt; i.Id == id

现在来看看。这是什么?给出一个Student对象返回一个bool。这是一个功能!

  • =&gt;是什么意思?标志?

    它是一个定义函数的运算符。论点位于左侧,正文位于右侧。

  • 它是如何运作的?

    假设您希望我编写一个函数,该函数接受List参数和我们正在讨论的函数,并返回匹配的学生而不使用Find方法。我可能会写这样的东西。

    学生FindStudent(列出学生,Func匹配) {     foreach(学生)       if(match(st))返回st;     返回 }

    你可能会发现一切都很熟悉,但是,我想,你可以想象的类型Func是一种从学生到布尔的函数。我也可以使用Predicate,你可以猜测它是学生谓词的一种类型。

    但是,你不需要我自己写这个或自己写这个,因为微软已经为我们做了这个。 Microsoft为Find()类的List<T>编写的代码与上述代码非常相似。

希望有所帮助!


这应该包括您提出的所有问题。但为了获得更广泛的图片,您可能还想看看:


可能对您有所帮助的一些分离说明:

  • Lambda表达式可能有多个参数,例如`(x,y)=&gt; x * x + y + 43'
  • lambda表达式的右侧可以是代码块,例如`(x,y)=&gt; {return x * x + y + 43;}'
  • 带有字符串的lambda表达式的类型和返回bool值的int参数是`Func'
  • 带有字符串参数的lambda表达式的类型和不返回任何内容的int参数是“Action”

答案 5 :(得分:0)

List<T>定义了一种方法Find(Predicate<T> match)

Predicate<T>是一个委托,可以引用与其签名

匹配的任何方法
bool Predicate(T param)

在您的情况下,您在学生列表Find上调用List<Student>方法,因此Find方法需要一个与以下签名匹配的函数:

bool MyFindMethod(Student param)

您可以在类中定义这样的方法,如下所示:

bool MyFindMethod(Student param)
{
    // Logic goes here
}

并将其传递给您的Find方法,如下所示:

students.Find(MyFindMethod)

您使用的方法既小又简单,因此在您的类中创建方法的开销不值得,因此lambda表达式允许您以非常简洁的方式定义相同的方法。

s => s.Id == id

相当于:

bool AnonymousMethod(Student param)
{
    return s.Id == id;
}

=>运算符左侧的项是传递给方法的参数,=>运算符右侧的项是方法体

请注意,编译器非常智能,可以确定参数(在我的示例中为s)的类型为Student,因此不需要指定。

如果您有其他类型的列表E.G。

public class Customer
{
    public string Name { get; set;}
}

public IList<Customer> customers = new List<Customer>();

然后编译器会推断该参数的类型为Customer,而不是学生。

customers.Find(c => c.Name == name);

请注意,参数可以按照您想要的名称命名,但通常保留为单个字母以使表达式简洁。

如果您了解所有这些,那么您将看到您的代码

students.Find(i => i.Id == id)

基本上是调用一个方法,该方法将Student作为参数并对其进行评估,以查看它是否与=>运算符右侧的条件匹配。如果参数符合条件(即,如果学生Idid变量匹配),则表达式将返回true。这告诉Find方法它已找到匹配项并将返回此对象。

我回答了与WPF相关的类似问题here,但在不同背景下的示例可能有助于您理解。