ฉันถูกถามคำถามนี้บ่อยมากและฉันคิดว่าฉันจะขอข้อมูลบางอย่างเกี่ยวกับวิธีอธิบายความแตกต่างได้ดีที่สุด
ฉันถูกถามคำถามนี้บ่อยมากและฉันคิดว่าฉันจะขอข้อมูลบางอย่างเกี่ยวกับวิธีอธิบายความแตกต่างได้ดีที่สุด
คำตอบ:
จริงๆแล้วมันเป็นสองสิ่งที่แตกต่างกันมาก "Delegate" เป็นชื่อของตัวแปรที่มีการอ้างอิงถึงเมธอดหรือแลมบ์ดาและแลมบ์ดาเป็นเมธอดที่ไม่มีชื่อถาวร
Lambdas ก็เหมือนกับวิธีอื่น ๆ มากยกเว้นความแตกต่างเล็กน้อย
ผู้แทนถูกกำหนดไว้เช่นนี้:
delegate Int32 BinaryIntOp(Int32 x, Int32 y);
ตัวแปรประเภท BinaryIntOp สามารถมี method หรือ labmda ที่กำหนดให้ก็ได้ตราบใดที่ลายเซ็นเหมือนกัน: อาร์กิวเมนต์ Int32 สองตัวและ Int32 return
แลมบ์ดาอาจถูกกำหนดไว้เช่นนี้:
BinaryIntOp sumOfSquares = (a, b) => a*a + b*b;
สิ่งที่ควรทราบอีกประการหนึ่งก็คือแม้ว่าประเภท Func และ Action ทั่วไปมักถูกมองว่าเป็น "ประเภทแลมบ์ดา" แต่ก็เหมือนกับผู้รับมอบสิทธิ์อื่น ๆ สิ่งที่ดีเกี่ยวกับพวกเขาคือพวกเขากำหนดชื่อให้กับผู้ร่วมประชุมประเภทใดก็ได้ที่คุณอาจต้องการ (มากถึง 4 พารามิเตอร์แม้ว่าคุณจะสามารถเพิ่มพารามิเตอร์ของคุณเองได้) ดังนั้นหากคุณกำลังใช้ประเภทผู้รับมอบสิทธิ์ที่หลากหลาย แต่ไม่มีมากกว่าหนึ่งครั้งคุณสามารถหลีกเลี่ยงการทำให้โค้ดของคุณยุ่งเหยิงด้วยการประกาศมอบสิทธิ์โดยใช้ Func และ Action
นี่คือภาพประกอบว่า Func และ Action "ไม่ใช่แค่สำหรับ lambdas":
Int32 DiffOfSquares(Int32 x, Int32 y)
{
return x*x - y*y;
}
Func<Int32, Int32, Int32> funcPtr = DiffOfSquares;
สิ่งที่มีประโยชน์อีกประการหนึ่งที่ควรทราบคือประเภทผู้รับมอบสิทธิ์ (ไม่ใช่วิธีการเอง) ที่มีลายเซ็นเดียวกัน แต่ชื่อต่างกันจะไม่ถูกส่งต่อกันโดยปริยาย ซึ่งรวมถึงผู้รับมอบสิทธิ์ Func และ Action อย่างไรก็ตามหากลายเซ็นเหมือนกันคุณสามารถโยนระหว่างลายเซ็นได้อย่างชัดเจน
ก้าวไปอีกขั้น .... ในฟังก์ชัน C # มีความยืดหยุ่นด้วยการใช้แลมบ์ดาและผู้ร่วมประชุม แต่ C # ไม่มี "ฟังก์ชันชั้นหนึ่ง" คุณสามารถใช้ชื่อของฟังก์ชันที่กำหนดให้กับตัวแปรผู้รับมอบสิทธิ์เพื่อสร้างวัตถุที่เป็นตัวแทนของฟังก์ชันนั้น แต่มันเป็นเคล็ดลับของคอมไพเลอร์จริงๆ หากคุณเริ่มต้นคำสั่งโดยเขียนชื่อฟังก์ชันตามด้วยจุด (เช่นพยายามให้สมาชิกเข้าถึงฟังก์ชันนั้นเอง) คุณจะพบว่าไม่มีสมาชิกที่จะอ้างอิง ไม่ใช่แม้แต่คนที่มาจาก Object ซึ่งจะป้องกันไม่ให้โปรแกรมเมอร์ทำสิ่งที่เป็นประโยชน์ (และอาจเป็นอันตรายแน่นอน) เช่นการเพิ่มวิธีการขยายที่สามารถเรียกใช้กับฟังก์ชันใด ๆ สิ่งที่ดีที่สุดที่คุณสามารถทำได้คือขยายคลาส Delegate ซึ่งก็มีประโยชน์เช่นกัน แต่ก็ไม่มากนัก
อัปเดต: ดูคำตอบของ Karg ที่แสดงความแตกต่างระหว่างตัวแทนที่ไม่ระบุชื่อกับวิธีการและแลมบ์ดา
อัปเดต 2: James Hartให้ความสำคัญแม้ว่าจะมีเทคนิคมาก แต่โปรดทราบว่า lambdas และ delegates ไม่ใช่เอนทิตี. NET (เช่น CLR ไม่มีแนวคิดเกี่ยวกับผู้รับมอบสิทธิ์หรือแลมบ์ดา) แต่เป็นเฟรมเวิร์กและโครงสร้างภาษา
คำถามมีความคลุมเครือเล็กน้อยซึ่งอธิบายถึงความแตกต่างอย่างกว้างขวางในคำตอบที่คุณได้รับ
คุณถามจริงว่าความแตกต่างระหว่าง lambdas และ delegates ใน. NET framework คืออะไร นั่นอาจเป็นหนึ่งในหลาย ๆ สิ่ง คุณถามว่า:
อะไรคือความแตกต่างระหว่างนิพจน์แลมบ์ดาและตัวแทนที่ไม่ระบุชื่อในภาษา C # (หรือ VB.NET)
อะไรคือความแตกต่างระหว่างอ็อบเจ็กต์ System.Linq.Expressions.LambdaExpression และอ็อบเจ็กต์ System.Delegate ใน. NET 3.5
หรือบางสิ่งบางอย่างระหว่างหรือรอบ ๆ สุดขั้วเหล่านั้น?
บางคนดูเหมือนจะพยายามให้คำตอบแก่คุณสำหรับคำถาม 'อะไรคือความแตกต่างระหว่างนิพจน์ C # Lambda และ. NET System.Delegate?' ซึ่งไม่สมเหตุสมผลเลย
NET Framework ไม่เข้าใจแนวคิดของผู้รับมอบสิทธิ์ที่ไม่ระบุชื่อนิพจน์แลมบ์ดาหรือการปิดซึ่งเป็นสิ่งที่กำหนดโดยข้อกำหนดทางภาษา ลองนึกถึงวิธีที่คอมไพเลอร์ C # แปลนิยามของวิธีการไม่ระบุชื่อเป็นวิธีการบนคลาสที่สร้างขึ้นโดยมีตัวแปรสมาชิกเพื่อระงับสถานะปิด ถึง. NET ไม่มีอะไรที่ไม่ระบุชื่อเกี่ยวกับผู้รับมอบสิทธิ์ เป็นเพียงการไม่ระบุตัวตนของโปรแกรมเมอร์ C # ที่เขียนมัน นั่นเป็นความจริงพอ ๆ กันกับนิพจน์แลมบ์ดาที่กำหนดให้กับประเภทผู้รับมอบสิทธิ์
อะไร. NET ไม่เข้าใจคือความคิดของผู้รับมอบสิทธิ์ให้ผู้อื่น - ประเภทที่อธิบายลายเซ็นวิธีหนึ่งอินสแตนซ์ซึ่งเป็นตัวแทนที่ถูกผูกไว้ทั้งการโทรไปยังวิธีการเฉพาะบนวัตถุที่เฉพาะเจาะจงหรือโทรไม่ได้ผูกไว้กับวิธีการหนึ่งในประเภทใดประเภทหนึ่งที่สามารถเรียกใช้กับ วัตถุประเภทนั้น ๆ โดยที่วิธีการดังกล่าวเป็นไปตามลายเซ็นดังกล่าว ประเภทดังกล่าวทั้งหมดสืบทอดมาจาก System.Delegate
.NET 3.5 ยังแนะนำเนมสเปซ System.Linq.Expressions ซึ่งมีคลาสสำหรับอธิบายนิพจน์โค้ด - และยังสามารถแสดงถึงการเรียกที่ถูกผูกไว้หรือไม่ถูกผูกไว้กับเมธอดในบางประเภทหรืออ็อบเจ็กต์ จากนั้นอินสแตนซ์ LambdaExpression สามารถคอมไพล์เป็นผู้รับมอบสิทธิ์จริงได้ (โดยวิธีการแบบไดนามิกที่ขึ้นอยู่กับโครงสร้างของนิพจน์นั้นถูกสร้างโค้ดและตัวชี้ที่มอบสิทธิ์จะถูกส่งกลับ)
ใน C # คุณสามารถสร้างอินสแตนซ์ของ System.Expressions.Expression types โดยการกำหนด lambda expression ให้กับตัวแปรชนิดดังกล่าวซึ่งจะสร้างโค้ดที่เหมาะสมเพื่อสร้างนิพจน์ที่รันไทม์
แน่นอนถ้าคุณถูกขอให้สิ่งที่แตกต่างระหว่างการแสดงออกแลมบ์ดาและวิธีการที่ไม่ระบุชื่อใน C # หลังจากทั้งหมดแล้วทั้งหมดนี้เป็น irelevant สวยมากและในกรณีที่ความแตกต่างหลักเป็นระยะเวลาสั้น ๆ ซึ่งชะโงกตัวไปได้รับมอบหมายที่ไม่ระบุชื่อเมื่อคุณสวม' ไม่สนใจเกี่ยวกับพารามิเตอร์และไม่ได้วางแผนที่จะส่งคืนค่าและไปยัง lambdas เมื่อคุณต้องการพิมพ์พารามิเตอร์ที่อ้างอิงและประเภทการส่งคืน
และแลมบ์ดานิพจน์สนับสนุนการสร้างนิพจน์
ความแตกต่างอย่างหนึ่งคือผู้รับมอบสิทธิ์ที่ไม่ระบุชื่อสามารถละเว้นพารามิเตอร์ได้ในขณะที่แลมบ์ดาต้องตรงกับลายเซ็นที่แน่นอน ให้:
public delegate string TestDelegate(int i);
public void Test(TestDelegate d)
{}
คุณสามารถเรียกมันได้ในสี่วิธีต่อไปนี้ (โปรดทราบว่าบรรทัดที่สองมีผู้รับมอบสิทธิ์ที่ไม่ระบุตัวตนซึ่งไม่มีพารามิเตอร์ใด ๆ ):
Test(delegate(int i) { return String.Empty; });
Test(delegate { return String.Empty; });
Test(i => String.Empty);
Test(D);
private string D(int i)
{
return String.Empty;
}
คุณไม่สามารถส่งผ่านในนิพจน์แลมบ์ดาที่ไม่มีพารามิเตอร์หรือวิธีการที่ไม่มีพารามิเตอร์ สิ่งเหล่านี้ไม่ได้รับอนุญาต:
Test(() => String.Empty); //Not allowed, lambda must match signature
Test(D2); //Not allowed, method must match signature
private string D2()
{
return String.Empty;
}
ผู้รับมอบสิทธิ์เทียบเท่ากับตัวชี้ฟังก์ชัน / ตัวชี้วิธีการ / การเรียกกลับ (เลือกของคุณ) และ lambdas เป็นฟังก์ชันที่ไม่ระบุตัวตนที่ค่อนข้างง่าย อย่างน้อยนั่นคือสิ่งที่ฉันบอกผู้คน
ฉันไม่มีประสบการณ์มากมายกับสิ่งนี้ แต่วิธีที่ฉันจะอธิบายก็คือผู้รับมอบสิทธิ์เป็นเครื่องห่อหุ้มฟังก์ชันใด ๆ ในขณะที่นิพจน์แลมบ์ดาเป็นฟังก์ชันที่ไม่ระบุตัวตน
ผู้รับมอบสิทธิ์เป็นเพียงตัวชี้ฟังก์ชันเท่านั้น แลมบ์ดาสามารถเปลี่ยนเป็นผู้รับมอบสิทธิ์ได้ แต่ก็สามารถเปลี่ยนเป็นแผนภูมินิพจน์ LINQ ได้เช่นกัน ตัวอย่างเช่น
Func<int, int> f = x => x + 1;
Expression<Func<int, int>> exprTree = x => x + 1;
บรรทัดแรกสร้างตัวแทนในขณะที่บรรทัดที่สองสร้างแผนภูมินิพจน์
lambdas เป็นเพียงน้ำตาลที่เป็นประโยคต่อตัวแทน คอมไพเลอร์ลงท้ายด้วยการแปลง lambdas เป็นผู้รับมอบสิทธิ์
สิ่งเหล่านี้เหมือนกันฉันเชื่อว่า:
Delegate delegate = x => "hi!";
Delegate delegate = delegate(object x) { return "hi";};
Delegate
จาก 'delegate' ซึ่งเป็นคีย์เวิร์ด
ผู้รับมอบสิทธิ์คือลายเซ็นของฟังก์ชัน สิ่งที่ต้องการ
delegate string MyDelegate(int param1);
ผู้รับมอบสิทธิ์ไม่ได้ใช้ร่างกาย
แลมบ์ดาเป็นการเรียกใช้ฟังก์ชันที่ตรงกับลายเซ็นของผู้รับมอบสิทธิ์ สำหรับผู้รับมอบสิทธิ์ข้างต้นคุณอาจใช้;
(int i) => i.ToString();
(int i) => "ignored i";
(int i) => "Step " + i.ToString() + " of 10";
Delegate
ประเภทเป็นชื่อที่ตั้งไม่ดีแม้ว่า; การสร้างออบเจ็กต์ประเภทDelegate
สร้างตัวแปรที่สามารถเก็บฟังก์ชันได้ไม่ว่าจะเป็น lambdas วิธีการแบบคงที่หรือวิธีคลาส
ผู้รับมอบสิทธิ์คือการอ้างอิงถึงวิธีการที่มีรายการพารามิเตอร์เฉพาะและประเภทการส่งคืน อาจรวมถึงวัตถุหรือไม่ก็ได้
แลมบ์ดานิพจน์เป็นรูปแบบของฟังก์ชันที่ไม่ระบุชื่อ
ผู้รับมอบสิทธิ์คือคิวของตัวชี้ฟังก์ชันการเรียกใช้ผู้รับมอบสิทธิ์อาจเรียกใช้หลายวิธี แลมบ์ดาเป็นการประกาศเมธอดแบบไม่ระบุตัวตนซึ่งคอมไพลเลอร์อาจตีความแตกต่างกันขึ้นอยู่กับบริบทที่ใช้เป็น
คุณสามารถรับผู้รับมอบสิทธิ์ที่ชี้ไปที่นิพจน์แลมบ์ดาเป็นวิธีการโดยการแคสต์ลงในผู้รับมอบสิทธิ์หรือหากส่งต่อเป็นพารามิเตอร์ไปยังเมธอดที่คาดว่าจะมีประเภทผู้รับมอบสิทธิ์เฉพาะคอมไพเลอร์จะส่งให้คุณ การใช้มันภายในคำสั่ง LINQ แลมบ์ดาจะถูกแปลโดยคอมไพเลอร์เป็นแผนภูมินิพจน์แทนที่จะเป็นเพียงผู้รับมอบสิทธิ์
ความแตกต่างจริงๆคือแลมบ์ดาเป็นวิธีที่สั้นในการกำหนดวิธีการภายในนิพจน์อื่นในขณะที่ผู้รับมอบสิทธิ์เป็นประเภทวัตถุจริง
เป็นที่ชัดเจนว่าคำถามควรจะเป็น "lambdas กับanonymousต่างกันอย่างไรผู้ได้รับมอบหมายที่อย่างไร" จากคำตอบทั้งหมดที่นี่มีเพียงคนเดียวเท่านั้นที่ทำให้ถูกต้อง - ความแตกต่างที่สำคัญคือ lambdas สามารถใช้เพื่อสร้างต้นไม้แสดงออกเช่นเดียวกับผู้รับมอบสิทธิ์
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับ MSDN: http://msdn.microsoft.com/en-us/library/bb397687.aspx
ผู้รับมอบสิทธิ์เป็นเพียงการพิมพ์โครงสร้างสำหรับฟังก์ชัน คุณสามารถทำสิ่งเดียวกันกับการพิมพ์เล็กน้อยและใช้คลาสที่ไม่ระบุตัวตนที่ใช้อินเทอร์เฟซหรือคลาสนามธรรม แต่จะกลายเป็นโค้ดจำนวนมากเมื่อต้องการเพียงฟังก์ชันเดียว
แลมด้ามาจากแนวคิดเรื่องแคลคูลัสแลมบ์ดาของคริสตจักรอลองโซในทศวรรษที่ 1930 เป็นวิธีการสร้างฟังก์ชันแบบไม่ระบุตัวตน สิ่งเหล่านี้มีประโยชน์อย่างยิ่งสำหรับการเขียนฟังก์ชัน
ดังนั้นในขณะที่บางคนอาจบอกว่าแลมบ์ดาเป็นน้ำตาลเชิงไวยากรณ์สำหรับผู้ร่วมประชุม แต่ฉันก็บอกว่าผู้ได้รับมอบหมายเป็นสะพานในการผ่อนคลายผู้คนให้เป็นแลมบ์ดาใน c #
พื้นฐานบางอย่างที่นี่ "Delegate" เป็นชื่อของตัวแปรที่มีการอ้างอิงถึงเมธอดหรือแลมบ์ดา
นี่เป็นวิธีที่ไม่ระบุตัวตน -
(string testString) => { Console.WriteLine(testString); };
เนื่องจากวิธีการที่ไม่ระบุชื่อไม่มีชื่อใด ๆ เราจึงต้องมีผู้รับมอบสิทธิ์ซึ่งเราสามารถกำหนดวิธีการหรือนิพจน์ทั้งสองนี้ได้ สำหรับ Ex.
delegate void PrintTestString(string testString); // declare a delegate
PrintTestString print = (string testString) => { Console.WriteLine(testString); };
print();
เช่นเดียวกับนิพจน์แลมบ์ดา โดยปกติแล้วเราต้องการผู้รับมอบสิทธิ์เพื่อใช้งาน
s => s.Age > someValue && s.Age < someValue // will return true/false
เราสามารถใช้ func delegate เพื่อใช้สำนวนนี้
Func< Student,bool> checkStudentAge = s => s.Age > someValue && s.Age < someValue ;
bool result = checkStudentAge ( Student Object);
Lambdas เป็นเวอร์ชันที่เรียบง่ายของผู้ร่วมประชุม พวกเขามีคุณสมบัติบางอย่างของการปิดเช่นผู้รับมอบสิทธิ์ที่ไม่ระบุชื่อ แต่ยังช่วยให้คุณใช้การพิมพ์โดยนัยได้ แลมด้าเช่นนี้:
something.Sort((x, y) => return x.CompareTo(y));
มีความกระชับมากกว่าสิ่งที่คุณสามารถทำได้กับผู้รับมอบสิทธิ์:
something.Sort(sortMethod);
...
private int sortMethod(SomeType one, SomeType two)
{
one.CompareTo(two)
}
นี่เป็นตัวอย่างที่ฉันวางไว้ในบล็อกง่อย ๆ ของฉัน สมมติว่าคุณต้องการอัปเดตป้ายกำกับจากเธรดผู้ปฏิบัติงาน ฉันมี 4 ตัวอย่างวิธีการอัปเดตป้ายกำกับนั้นจาก 1 ถึง 50 โดยใช้ตัวแทนผู้ร่วมประชุมอานนท์และแลมบ์ดา 2 ประเภท
private void button2_Click(object sender, EventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerAsync();
}
private delegate void UpdateProgDelegate(int count);
private void UpdateText(int count)
{
if (this.lblTest.InvokeRequired)
{
UpdateProgDelegate updateCallBack = new UpdateProgDelegate(UpdateText);
this.Invoke(updateCallBack, new object[] { count });
}
else
{
lblTest.Text = count.ToString();
}
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
/* Old Skool delegate usage. See above for delegate and method definitions */
for (int i = 0; i < 50; i++)
{
UpdateText(i);
Thread.Sleep(50);
}
// Anonymous Method
for (int i = 0; i < 50; i++)
{
lblTest.Invoke((MethodInvoker)(delegate()
{
lblTest.Text = i.ToString();
}));
Thread.Sleep(50);
}
/* Lambda using the new Func delegate. This lets us take in an int and
* return a string. The last parameter is the return type. so
* So Func<int, string, double> would take in an int and a string
* and return a double. count is our int parameter.*/
Func<int, string> UpdateProgress = (count) => lblTest.Text = count.ToString();
for (int i = 0; i < 50; i++)
{
lblTest.Invoke(UpdateProgress, i);
Thread.Sleep(50);
}
/* Finally we have a totally inline Lambda using the Action delegate
* Action is more or less the same as Func but it returns void. We could
* use it with parameters if we wanted to like this:
* Action<string> UpdateProgress = (count) => lblT…*/
for (int i = 0; i < 50; i++)
{
lblTest.Invoke((Action)(() => lblTest.Text = i.ToString()));
Thread.Sleep(50);
}
}
ฉันคิดว่าคำถามของคุณเกี่ยวข้องกับ c # ไม่ใช่. NET เนื่องจากความคลุมเครือของคำถามของคุณเนื่องจาก. NET ไม่ได้อยู่คนเดียว - นั่นคือการไม่มี c # - ความเข้าใจในตัวแทนและการแสดงออกของแลมบ์ดา
A ( ปกติในทางตรงกันข้ามกับที่เรียกว่าผู้รับมอบสิทธิ์ทั่วไปcf ในภายหลัง) ผู้รับมอบสิทธิ์ควรถูกมองว่าเป็นชนิดของ c ++ typedef
ของประเภทตัวชี้ฟังก์ชันตัวอย่างเช่นใน c ++:
R (*thefunctionpointer) ( T ) ;
typedef เป็นชนิดthefunctionpointer
ซึ่งเป็นประเภทของตัวชี้ไปยังฟังก์ชั่นการใช้วัตถุชนิดนั้นและกลับมาวัตถุของการพิมพ์T
R
คุณจะใช้มันดังนี้:
thefunctionpointer = &thefunction ;
R r = (*thefunctionpointer) ( t ) ; // where t is of type T
ซึ่งthefunction
จะเป็นฟังก์ชันที่รับT
และส่งคืนไฟล์R
ไฟล์.
ใน c # คุณจะไป
delegate R thedelegate( T t ) ; // and yes, here the identifier t is needed
และคุณจะใช้มันในลักษณะนี้:
thedelegate thedel = thefunction ;
R r = thedel ( t ) ; // where t is of type T
ซึ่งthefunction
จะเป็นฟังก์ชันที่รับT
และส่งคืนไฟล์R
ไฟล์. สำหรับผู้ได้รับมอบหมายหรือที่เรียกว่าผู้รับมอบสิทธิ์ปกติ
ตอนนี้คุณยังมีตัวแทนทั่วไปใน c # ซึ่งเป็นผู้รับมอบสิทธิ์ที่เป็นแบบทั่วไปกล่าวคือ "เทมเพลต" เพื่อที่จะพูดโดยใช้นิพจน์ c ++ พวกเขาถูกกำหนดไว้เช่นนี้:
public delegate TResult Func<in T, out TResult>(T arg);
และคุณสามารถใช้มันได้ดังนี้:
Func<double, double> thefunctor = thefunction2; // call it a functor because it is
// really as a functor that you should
// "see" it
double y = thefunctor(2.0);
ซึ่งthefunction2
เป็นฟังก์ชั่นการใช้เป็นอาร์กิวเมนต์และกลับdouble
เป็นฟังก์ชั่นการใช้เป็นอาร์กิวเมนต์และกลับ
ทีนี้ลองนึกดูว่าแทนที่จะthefunction2
ใช้ "ฟังก์ชัน" ที่ไม่มีที่ไหนกำหนดไว้สำหรับตอนนี้ด้วยคำสั่งและฉันจะไม่ใช้ในภายหลัง จากนั้น c # ให้เราใช้นิพจน์ของฟังก์ชันนี้ โดยการแสดงออกของผมหมายถึง "คณิตศาสตร์" (หรือการทำงานที่จะติดโปรแกรม) การแสดงออกของมันเช่น: ไปdouble x
ผมจะเชื่อมโยง double
x*x
ในวิชาคณิตศาสตร์ที่คุณเขียนนี้โดยใช้"การ \ mapsto สัญลักษณ์" ใน c # มีการยืมสัญกรณ์การทำงาน: =>
. ตัวอย่างเช่น:
Func<double, double> thefunctor = ( (double x) => x * x ); // outer brackets are not
// mandatory
(double x) => x * x
คือการแสดงออกการแสดงออกไม่ใช่ประเภทในขณะที่ผู้รับมอบสิทธิ์ (ทั่วไปหรือไม่) เป็น
ศีลธรรม? ในตอนท้ายผู้รับมอบสิทธิ์คืออะไร (resp. generic delegate) ถ้าไม่ใช่ประเภทตัวชี้ฟังก์ชัน (resp. wrap + smart + ประเภทตัวชี้ฟังก์ชันทั่วไป) ห๊ะ? อื่น ๆ อีก ! ดูสิ่งนี้และสิ่งนั้น
เวอร์ชันที่ย่อมากเกินไปคือแลมบ์ดาเป็นเพียงชวเลขสำหรับฟังก์ชันที่ไม่ระบุตัวตน ผู้รับมอบสิทธิ์สามารถทำหน้าที่ได้มากกว่าฟังก์ชันที่ไม่ระบุตัวตน: สิ่งต่างๆเช่นเหตุการณ์การโทรแบบอะซิงโครนัสและเครือข่ายวิธีการต่างๆ