[英]in c#, meaning of => sign
有一個名為Student
的類,它具有Id
, Name
和Phone
屬性。 在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()
編寫的代碼與上面的內容非常相似。
希望有所幫助!
這應該涵蓋你所要求的一切。 但為了獲得更廣泛的圖片,您可能還想看看:
一些可能對您有所幫助的離別說明:
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
作為參數並對其進行評估,以查看它是否與=>
運算符右側的條件匹配。 如果參數符合條件(即,如果學生Id
與id
變量匹配),則表達式將返回true。 這告訴Find
方法它已找到匹配項並將返回此對象。
我在這里回答了一個與WPF相關的類似問題,但是在不同背景下的示例可能有助於您的理解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.