簡體   English   中英

在c#中,意思是=>符號

[英]in c#, meaning of => sign

有一個名為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)做什么? 這是什么意思? => sign是什么意思? 它是如何工作的?

它們稱為Lambda表達式...... Lambda表達式使用特殊語法。 它們允許將函數用作變量或字段等數據。 lambda表達式語法使用=>運算符。 這將分隔匿名函數的參數和語句體。

你可以把它作為“去”。

=>運算符可以讀作“轉到”,並且在聲明lambda表達式時總是使用它。 lambda表達式允許您將具有可執行語句的函數用作參數,變量或字段。

請參閱MSDN上的此鏈接以更好地理解它。

這是一個goes to操作者(或拉姆達運營商 ),其在使用lambda表達式 (匿名方法創建)對輸入變量從拉姆達體分離。

在您的示例students.Find(i => i.Id== id)輸入變量i轉到lambda body i.Id == id (即作為匿名方法參數傳遞)。


另請查看您正在使用的List<T>.Find方法。 它接受類型為T 謂詞 ,在您的情況下將為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字段。

=>是一個goesto運算符,這個表達式是lambda expresion

msdn

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元素。

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

情況就是這樣。 您有一個學生對象列表和您感興趣的學生的ID。如果學生對象存儲在一個集合中,您自己定義了一個帶有ID的Find方法並返回具有該id的學生,您的代碼看起來像這樣:

Student aStudent = students.Find(id);

但是,當Microsoft定義了通用List集合時,他們可能不知道如何使用它 - 而且他們不想知道。 他們希望讓您有機會將它與Student對象或您能想到的任何其他類型一起使用。 但這意味着他們必須通過提供只有您知道的問題信息,為您提供一種方法來找到您所追求的元素。 在這個特定的實例中,您知道您正在尋找存儲在學生列表中的Student對象,該對象的Id字段與您擁有的ID相匹配。 如果我給你一個物品,讓我們稱之為i ,你可以通過執行以下檢查告訴我它是否是你要找的物品:

i.Id == id 

如果我給你一個叫做student的對象,你就可以通過執行測試來執行測試student你可以告訴我你是否是你所追求的那個

student.Id == id

(如果您沒有id但是其他一些唯一確定Student對象的信息(即一個鍵),那么您需要指定一個不同的條件。靈活性非常重要!)

那么,現在我們到達下一個問題。

  • 這是什么意思?

    讓我們創建一個約定。 您將確定要將學生對象稱為什么,然后您將提供一個適當的檢查來挑選您所學的學生。 您將表示該學生的標識符放在=>的左側,並將檢查條件放在右側。 因此你可以有類似的東西:

    student => student.Id == id

或者如果你喜歡提到正在討論的學生對象i不是student ,那么你可以寫

i => i.Id == id

現在來看看。 這是什么? 給出一個Student對象返回一個bool。 這是一個功能!

  • => sign是什么意思?

    它是一個定義函數的運算符。 論點位於左側,正文位於右側。

  • 它是如何工作的?

    假設您希望我編寫一個函數,該函數接受List參數和一個函數,例如我們正在討論的函數,並返回匹配的學生,而不使用Find方法。 我可能會寫這樣的東西。

    學生FindStudent(列出學生,Func匹配){foreach(學生在學生中)if(match(st))return st; 返回 }

    你可能會發現一切都很熟悉,除了我想,你可以想象的類型Func是一種從學生到布爾的函數。 我也可以使用Predicate,你可以猜測它是學生謂詞的一種類型。

    但是,您不需要我自己寫這個或自己寫這個,因為Microsoft已經為我們這樣做了。 Microsoft為List<T>類的Find()編寫的代碼與上面的內容非常相似。

希望有所幫助!


這應該涵蓋你所要求的一切。 但為了獲得更廣泛的圖片,您可能還想看看:


一些可能對您有所幫助的離別說明:

  • Lambda表達式可能有多個參數,例如`(x,y)=> x * x + y + 43'
  • lambda表達式的右側可以是代碼塊,例如`(x,y)=> {return x * x + y + 43;}'
  • 帶有字符串的lambda表達式的類型和返回bool值的int參數是`Func'
  • 帶有字符串參數的lambda表達式的類型和不返回任何內容的int參數是“Action”

List<T>定義了一個方法Find(Predicate<T> match)

Predicate<T>是一個委托,可以引用與其簽名匹配的任何方法

bool Predicate(T param)

在您的情況下,您在學生List<Student>上調用Find方法,因此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類型,因此不需要指定。

如果你有一個其他類型的EG列表

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

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

然后編譯器會推斷該參數是Customer類型而不是student類型。

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

請注意,參數可以命名為您想要的任何名稱,但通常保留為單個字母以使表達式簡潔。

如果您了解所有這些,那么您將看到您的代碼

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

基本上調用一個方法,該方法將Student作為參數並對其進行評估,以查看它是否與=>運算符右側的條件匹配。 如果參數符合條件(即,如果學生Idid變量匹配),則表達式將返回true。 這告訴Find方法它已找到匹配項並將返回此對象。

在這里回答了一個與WPF相關的類似問題,但是在不同背景下的示例可能有助於您的理解。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM