2008-09-16 9 views
52

मैं इस सवाल का एक बहुत कुछ पूछे जाते और मैंने सोचा कि मैं कैसे सबसे अच्छा अंतर का वर्णन करने के बारे में कुछ इनपुट मांगना चाहते हैं।.NET Framework में लैम्बडास और प्रतिनिधियों के बीच क्या अंतर है?

+2

"प्रतिनिधियों" द्वारा आपका मतलब प्रतिनिधि प्रकार या अज्ञात प्रतिनिधि हैं? वे भी अलग हैं। –

+0

[प्रतिनिधि कीवर्ड बनाम लैम्ब्डा नोटेशन] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/299703/delegate-keyword-vs-lambda-notation) – nawfal

उत्तर

64

वे वास्तव में दो बहुत ही अलग चीजें हैं। "प्रतिनिधि" वास्तव में एक चर के लिए नाम है जो किसी विधि या लैम्ब्डा का संदर्भ रखता है, और एक लैम्ब्डा स्थायी नाम के बिना एक विधि है।

दो सूक्ष्म मतभेदों को छोड़कर लैम्ब्डा अन्य विधियों की तरह बहुत अधिक हैं।

  1. एक सामान्य विधि एक "statement" में परिभाषित किया गया है और एक स्थायी नाम से बंधा है, जबकि एक लैम्ब्डा एक "expression" में "मक्खी पर" परिभाषित और कोई स्थायी नाम है जाता है।
  2. कुछ लैम्बडा का उपयोग .NET अभिव्यक्ति पेड़ों के साथ किया जा सकता है, जबकि विधियां नहीं हो सकती हैं।

एक प्रतिनिधि इस तरह परिभाषित किया गया है:

delegate Int32 BinaryIntOp(Int32 x, Int32 y); 

प्रकार का एक चर BinaryIntOp या तो एक विधि या एक labmda में डाला गया हो सकता है, जब तक हस्ताक्षर के रूप में एक ही है: दो Int32 तर्क, और एक इंट 32 रिटर्न।

एक लैम्ब्डा इस तरह परिभाषित किया जा सकता है:

BinaryIntOp sumOfSquares = (a, b) => a*a + b*b; 

नोट करने के लिए एक और बात है कि हालांकि सामान्य समारोह और कार्रवाई प्रकार अक्सर "लैम्ब्डा प्रकार" माना जाता है, वे तो बस किसी भी अन्य प्रतिनिधियों की तरह हैं। उनके बारे में अच्छी बात यह है कि वे अनिवार्य रूप से किसी भी प्रकार के प्रतिनिधि के लिए एक नाम परिभाषित करते हैं जो आपको चाहिए (4 पैरामीटर तक, हालांकि आप निश्चित रूप से अपना स्वयं का अधिक जोड़ सकते हैं)। इसलिए यदि आप विभिन्न प्रकार के प्रतिनिधि प्रकारों का उपयोग कर रहे हैं, लेकिन एक से अधिक बार नहीं, तो आप Func और Action का उपयोग करके प्रतिनिधि घोषणाओं के साथ अपने कोड को अव्यवस्थित करने से बच सकते हैं।

यहाँ कैसे Func और कार्रवाई कर रहे हैं "बस नहीं lambdas के लिए" का एक उदाहरण है:

Int32 DiffOfSquares(Int32 x, Int32 y) 
{ 
    return x*x - y*y; 
} 

Func<Int32, Int32, Int32> funcPtr = DiffOfSquares; 

पता करने के लिए एक और उपयोगी बात यह है कि प्रतिनिधि प्रकार समान हस्ताक्षर से (न तरीकों खुद को), लेकिन अलग-अलग नाम है होगा एक दूसरे के लिए निहित नहीं किया जा सकता है। इसमें फनक और एक्शन प्रतिनिधि शामिल हैं। हालांकि अगर हस्ताक्षर समान है, तो आप स्पष्ट रूप से उनके बीच कास्ट कर सकते हैं।

अतिरिक्त मील जा रहा है .... सी # कार्यों में लम्बदास और प्रतिनिधियों के उपयोग के साथ लचीला है। लेकिन सी # में "प्रथम श्रेणी के कार्य" नहीं हैं।आप उस फ़ंक्शन का प्रतिनिधित्व करने वाले ऑब्जेक्ट को अनिवार्य रूप से बनाने के लिए एक प्रतिनिधि चर के लिए आवंटित फ़ंक्शन का नाम उपयोग कर सकते हैं। लेकिन यह वास्तव में एक कंपाइलर चाल है। यदि आप एक डॉट के बाद फ़ंक्शन नाम लिखकर एक कथन शुरू करते हैं (यानी फ़ंक्शन पर सदस्य पहुंच करने का प्रयास करें) तो आप पाएंगे कि संदर्भ में कोई सदस्य नहीं हैं। ऑब्जेक्ट से भी नहीं। यह प्रोग्रामर को उपयोगी (और संभावित रूप से खतरनाक रूप से) करने से रोकता है जैसे किसी भी फ़ंक्शन पर एक्सटेंशन विधियों को जोड़ना। सबसे अच्छा आप कर सकते हैं प्रतिनिधि वर्ग खुद को बढ़ाता है, जो निश्चित रूप से भी उपयोगी है, लेकिन उतना ही नहीं।

अद्यतन: Karg's answer भी देखें अज्ञात प्रतिनिधियों बनाम विधियों & लैम्बडास के बीच अंतर को दर्शाते हुए।

अद्यतन 2: James Hart एक महत्वपूर्ण, हालांकि बहुत तकनीकी बनाता है, ध्यान दें कि लैम्बडा और प्रतिनिधि .NET इकाइयां नहीं हैं (यानी सीएलआर में एक प्रतिनिधि या लैम्ब्डा की कोई अवधारणा नहीं है), बल्कि वे ढांचे और भाषा संरचनाएं हैं।

+0

अच्छी व्याख्या। हालांकि मुझे लगता है कि आपका मतलब है "प्रथम श्रेणी के कार्यों", न कि "प्रथम श्रेणी की वस्तुओं"। :) – ibz

+1

आप सही हैं। मेरे पास लेखन के दौरान सजावट अलग थी ("सी # फ़ंक्शंस वास्तव में प्रथम श्रेणी की वस्तुएं नहीं हैं") और इसे बदलने के लिए भूल गए। धन्यवाद! –

-1

ठीक है, वास्तव में oversimplified संस्करण है जिसे लैम्ब्डा सिर्फ एक गुमनाम समारोह के लिए आशुलिपि है है। एक प्रतिनिधि केवल अज्ञात कार्यों की तुलना में बहुत कुछ कर सकता है: घटनाओं, एसिंक्रोनस कॉल, और एकाधिक विधि श्रृंखला जैसी चीजें।

+1

लैम्बडास ईवेंट हैंडलर के रूप में उपयोग किया जा सकता है; बटन। क्लिक करें + = (प्रेषक, eventArgs) => {संदेशबॉक्स। शो ("क्लिक करें"); } और असीमित रूप से नई प्रणाली। थ्रेडिंग। थ्रेड (() => कंसोल। राइट ("थ्रेड पर निष्पादित")) प्रारंभ करें(); –

3

मैं इस के साथ अनुभव के एक टन की जरूरत नहीं है, लेकिन जिस तरह से मैं इसे का वर्णन होगा कि एक प्रतिनिधि, किसी भी समारोह के चारों ओर एक आवरण है, जबकि एक लैम्ब्डा अभिव्यक्ति ही एक गुमनाम समारोह है।

12

प्रतिनिधि समारोह संकेत/विधि संकेत/कॉलबैक (अपने पिकअप लेने के लिए) के बराबर हैं, और lambdas काफी गुमनाम कार्यों को सरल बनाया गया है। कम से कम यही मैं लोगों को बताता हूं।

+0

बिल्कुल! इसमें कोई फर्क नही है"। वे दो स्वाभाविक रूप से अलग-अलग चीजें हैं। – ibz

+0

ब्रेवटी की सराहना की! –

2

लैम्बडास एक प्रतिनिधि पर सिंटैक्टिक चीनी हैं। कंपाइलर लैम्बडा को प्रतिनिधियों में परिवर्तित कर देता है।

ये वही कर रहे हैं, मेरा मानना ​​है कि:

Delegate delegate = x => "hi!"; 
Delegate delegate = delegate(object x) { return "hi";}; 
+1

इनमें से कोई भी उदाहरण संकलित नहीं है। यहां तक ​​कि यदि आप 'प्रतिनिधि' से 'प्रतिनिधि' के उदाहरण का नाम बदलते हैं, जो एक कीवर्ड है। –

2

एक प्रतिनिधि एक समारोह हस्ताक्षर है,

delegate string MyDelegate(int param1); 

प्रतिनिधि किसी शरीर को लागू नहीं करता है।

लैम्ब्डा एक फ़ंक्शन कॉल है जो प्रतिनिधि के हस्ताक्षर से मेल खाता है। उपर्युक्त प्रतिनिधि के लिए, आप इनमें से किसी का भी उपयोग कर सकते हैं;

(int i) => i.ToString(); 
(int i) => "ignored i"; 
(int i) => "Step " + i.ToString() + " of 10"; 

Delegate प्रकार का बुरी तरह नामित है; Delegate प्रकार का ऑब्जेक्ट बनाना वास्तव में एक वेरिएबल बनाता है जो फ़ंक्शंस रख सकता है - चाहे वे लैम्बा, स्थिर विधियां या कक्षा विधियां हों।

+0

जब आप MyDelegate प्रकार का एक चर बनाते हैं, तो यह वास्तव में रनटाइम प्रकार नहीं है। रनटाइम प्रकार प्रतिनिधि है।प्रतिनिधियों, भेड़ के बच्चे, और अभिव्यक्ति पेड़ संकलित कैसे होते हैं, इसमें संकलक चाल शामिल है, जो मुझे लगता है कि कोड उन चीज़ों को इंगित करता है जो सत्य नहीं हैं। –

3

एक प्रतिनिधि हमेशा मूल रूप से एक फ़ंक्शन पॉइंटर होता है। एक लैम्ब्डा एक प्रतिनिधि बन सकता है, लेकिन यह एक LINQ अभिव्यक्ति वृक्ष में भी बदल सकता है। उदाहरण के लिए,

Func<int, int> f = x => x + 1; 
Expression<Func<int, int>> exprTree = x => x + 1; 

पहली पंक्ति, एक प्रतिनिधि का उत्पादन है, जबकि दूसरा एक अभिव्यक्ति पेड़ पैदा करता है।

+1

यह सच है, लेकिन उनके बीच * अंतर * यह है कि * वे दो पूरी तरह से अलग अवधारणाएं हैं *। यह सेब और संतरे की तुलना की तरह है। दान शील्ड का जवाब देखें। – ibz

1

प्रतिनिधि वास्तव में कार्यों के लिए सिर्फ संरचनात्मक टाइपिंग कर रहे हैं। आप नाममात्र टाइपिंग और एक अज्ञात वर्ग को कार्यान्वित करने के साथ एक ही काम कर सकते हैं जो एक इंटरफ़ेस या अमूर्त वर्ग लागू करता है, लेकिन जब केवल एक फ़ंक्शन की आवश्यकता होती है तो बहुत सारे कोड होते हैं।

Lambda 1930 के दशक में अलोंजो चर्च के लैम्ब्डा पथरी के विचार से आता है। यह कार्यों को बनाने का एक अज्ञात तरीका है। वे रचना कार्यों

तो के लिए विशेष रूप से उपयोगी हो जाते हैं, जबकि कुछ लोग कह सकते लैम्ब्डा प्रतिनिधियों के लिए वाक्यात्मक चीनी है, मैं कहना है कि प्रतिनिधियों सी # में lambdas में लोगों को कम करने के लिए एक पुल रहे हैं होगा।

0

lambdas प्रतिनिधियों की सरलीकृत संस्करण है। उनके पास अज्ञात प्रतिनिधियों की तरह closure के कुछ गुण हैं, लेकिन यह आपको अंतर्निहित टाइपिंग का उपयोग करने की अनुमति भी देता है।इस तरह एक लैम्ब्डा:

something.Sort((x, y) => return x.CompareTo(y)); 

आप एक प्रतिनिधि के साथ क्या कर सकते की तुलना में बहुत अधिक संक्षिप्त है:

something.Sort(sortMethod); 
... 

private int sortMethod(SomeType one, SomeType two) 
{ 
    one.CompareTo(two) 
} 
+0

आपका मतलब है कि लैम्ब्डा सरलीकृत अज्ञात तरीकों की तरह हैं (प्रतिनिधि नहीं)। विधियों की तरह (अनाम या नहीं), उन्हें एक प्रतिनिधि चर के लिए असाइन किया जा सकता है। – Lucas

15

एक अंतर यह है कि एक गुमनाम प्रतिनिधि मानकों को छोड़ सकते हैं, जबकि एक लैम्ब्डा सटीक मेल खाना चाहिए है हस्ताक्षर। यह देखते हुए:

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; 
} 
0

एक उदाहरण है जो मैंने अपने लंगड़े ब्लॉग पर थोड़ी देर लगाया। मान लें कि आप एक कार्यकर्ता धागे से एक लेबल अद्यतन करना चाहते थे। मेरे पास प्रतिनिधियों, एनन प्रतिनिधियों और 2 प्रकार के लैम्ब्स का उपयोग करके 1 से 50 तक उस लेबल को अपडेट करने के 4 उदाहरण हैं।

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); 
     } 
    } 
2

एक प्रतिनिधि एक विशेष पैरामीटर सूची और वापसी प्रकार के साथ एक विधि के लिए एक संदर्भ है। यह एक वस्तु शामिल हो सकता है या नहीं भी हो सकता है।

एक लैम्ब्डा-अभिव्यक्ति अज्ञात फ़ंक्शन का एक रूप है।

1

एक प्रतिनिधि फ़ंक्शन पॉइंटर्स का एक कतार है, एक प्रतिनिधि का आह्वान करने से कई विधियां आ सकती हैं। एक लैम्ब्डा अनिवार्य रूप से एक अनाम विधि घोषणा है जिसे संकलक द्वारा अलग-अलग व्याख्या किया जा सकता है, इस पर निर्भर करता है कि इसका किस संदर्भ में उपयोग किया जाता है।

आप एक प्रतिनिधि को प्राप्त कर सकते हैं जो लैम्ब्डा अभिव्यक्ति को किसी प्रतिनिधि के रूप में पेश करके विधि के रूप में इंगित करता है, या यदि किसी विशिष्ट प्रतिनिधि प्रकार की अपेक्षा करने वाले किसी विधि के पैरामीटर के रूप में इसे पास कर रहा है तो संकलक इसे आपके लिए डालेगा। LINQ कथन के अंदर इसका उपयोग करके, लैम्ब्डा का संकलन कंप्रेसर द्वारा केवल एक प्रतिनिधि के बजाय एक अभिव्यक्ति पेड़ में किया जाएगा।

अंतर वास्तव में यह है कि एक लैम्ब्डा एक अन्य अभिव्यक्ति के अंदर एक विधि को परिभाषित करने का एक छोटा रास्ता है, जबकि एक प्रतिनिधि वास्तविक वस्तु प्रकार है।

23

प्रश्न थोड़ा अस्पष्ट है, जो आपको प्राप्त उत्तरों में व्यापक असमानता बताता है।

आपने वास्तव में पूछा कि .NET ढांचे में लैम्बडा और प्रतिनिधियों के बीच अंतर क्या है; यह कई चीजों में से एक हो सकता है। क्या आप पूछ रहे हैं:

  • सी # (या वीबी.नेट) भाषा में लैम्ब्डा अभिव्यक्तियों और अज्ञात प्रतिनिधियों के बीच क्या अंतर है?

  • System.Linq.Expressions.LambdaExpression ऑब्जेक्ट्स और सिस्टम के बीच क्या अंतर है। .NET 3.5 में ऑब्जेक्ट डिलीगेट करें?

  • या उन चरम सीमाओं के बीच कहीं या कहीं कुछ?

कुछ लोग सवाल का आप जवाब देने के लिए कोशिश कर रहा हो रहे हैं 'सी # लैम्ब्डा अभिव्यक्ति और नेट System.Delegate के बीच अंतर क्या है?' है, जो भावना की एक पूरी बहुत कुछ नहीं है।

.NET ढांचा स्वयं अज्ञात प्रतिनिधियों, लैम्ब्डा अभिव्यक्तियों या बंदियों की अवधारणाओं को समझ में नहीं आता है - ये सभी भाषा विनिर्देशों द्वारा परिभाषित सभी चीजें हैं। इस बारे में सोचें कि कैसे सी # कंपाइलर एक अज्ञात विधि की परिभाषा को जेनरेटेड क्लास पर एक विधि में बंद करने के लिए सदस्य चर के साथ सदस्य चर के साथ अनुवाद करता है; .NET के लिए, प्रतिनिधि के बारे में कुछ भी अज्ञात नहीं है; यह सी # प्रोग्रामर लिखने के लिए सिर्फ अज्ञात है। यह एक प्रतिनिधि प्रकार को सौंपा लैम्ब्डा अभिव्यक्ति के समान ही सच है। एक प्रकार है कि एक विधि हस्ताक्षर का वर्णन करता है, जो के उदाहरण के लिए एक विशेष पर एक विशेष विधि के लिए विशिष्ट वस्तुओं, या अनबाउंड कॉल पर विशिष्ट विधियों के लिए या तो बाध्य कॉल प्रतिनिधित्व करते हैं -

क्या नेट करता को समझने के लिए एक प्रतिनिधि का विचार है टाइप करें जिसे उस प्रकार के किसी भी ऑब्जेक्ट के खिलाफ बुलाया जा सकता है, जहां कहा गया तरीका कहा गया हस्ताक्षर का पालन करता है। इस तरह के सभी प्रकार सिस्टम से वंचित हैं। डिलीगेट।

.NET 3.5 सिस्टम भी प्रस्तुत करता है। लिंक्स.एक्सप्रेस नामस्थान, जिसमें कोड अभिव्यक्तियों का वर्णन करने के लिए कक्षाएं शामिल हैं - और इसलिए विशेष प्रकार या वस्तुओं पर विधियों के लिए बाध्य या अनबाउंड कॉल का प्रतिनिधित्व भी कर सकते हैं। LambdaExpression उदाहरणों को वास्तविक प्रतिनिधियों में संकलित किया जा सकता है (जिससे अभिव्यक्ति की संरचना के आधार पर गतिशील विधि कोडगेंडेड होती है, और इसके लिए एक प्रतिनिधि सूचक वापस लौटाया जाता है)।

सी # में आप सिस्टम के उदाहरण उत्पन्न कर सकते हैं। एक्सपेरियंस प्रकार, प्रकार के चर के लिए लैम्ब्डा अभिव्यक्ति निर्दिष्ट करके, जो रनटाइम पर अभिव्यक्ति का निर्माण करने के लिए उपयुक्त कोड का उत्पादन करेगा।

बेशक

, यदि आप थे पूछ क्या अंतर लैम्ब्डा भाव और सी # में गुमनाम तरीकों के बीच है, सब के बाद, तो यह सब काफी irelevant है, और उस मामले में प्राथमिक अंतर संक्षिप्तता है, जो की ओर leans है गुमनाम प्रतिनिधि जब आप पैरामीटर की परवाह नहीं करते हैं और मूल्य को वापस करने की योजना नहीं बनाते हैं, और जब आप संदर्भित पैरामीटर और रिटर्न प्रकार टाइप करना चाहते हैं तो लैम्ब्डा की ओर।

और लैम्ब्डा अभिव्यक्ति समर्थन अभिव्यक्ति पीढ़ी।

+2

महान जानकारी! आपने मुझे परावर्तक को आग लगाने और आईएल को देखने के लिए प्रेरित किया। मुझे नहीं पता था कि लैम्ब्स के परिणामस्वरूप कक्षाएं उत्पन्न हुईं, लेकिन अब यह सही समझ में आता है कि मैं इसके बारे में सोचता हूं। –

2

यह स्पष्ट है कि सवाल यह था कि "लैम्बडास और अज्ञात प्रतिनिधियों के बीच क्या अंतर है?" यहां सभी उत्तरों में से केवल एक व्यक्ति को यह सही मिला - मुख्य अंतर यह है कि लैम्बडा का उपयोग अभिव्यक्ति वृक्षों और प्रतिनिधियों को बनाने के लिए किया जा सकता है।

आप MSDN पर अधिक पढ़ सकते हैं: http://msdn.microsoft.com/en-us/library/bb397687.aspx

0

मुझे लगता है कि आपके सवाल का चिंताओं C# और नहीं .नेट, आपके सवाल की अस्पष्टता, .NET अकेले नहीं मिलता है के रूप में की वजह से - जो है, सी # के बिना - प्रतिनिधियों और लैम्ब्डा अभिव्यक्तियों की समझ।

:

एक प्रतिनिधि ग की ++ एक समारोह सूचक प्रकार के typedef एक प्रकार के रूप में देखा जाना चाहिए, सी में उदाहरण के लिए ++ (सामान्य, विपक्ष में इतना सामान्य प्रतिनिधियों, सीएफ बाद में कहा जाता है)

R (*thefunctionpointer) (T) ; 

टाइपपीफ का प्रकार thefunctionpointer जो T प्रकार की ऑब्जेक्ट लेते हुए फ़ंक्शन के पॉइंटर्स का प्रकार है और R प्रकार का ऑब्जेक्ट लौटा रहा है।आप इसे इस तरह का प्रयोग करेंगे:

thefunctionpointer = &thefunction ; 
R r = (*thefunctionpointer) (t) ; // where t is of type T 

जहां thefunction होगा एक समारोह एक T ले रहे हैं और एक R लौटने।

सी # में आप के लिए

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 लौटने होगा। यह प्रतिनिधियों के लिए है, इसलिए सामान्य प्रतिनिधियों को बुलाया जाता है।

अब, आपके पास सी # में जेनेरिक प्रतिनिधि भी हैं, जो प्रतिनिधि हैं जो यानी हैं जो कि एक सी ++ अभिव्यक्ति का उपयोग करके बोलने के लिए "टेम्पलेट" हैं। वे इस तरह परिभाषित कर रहे हैं:

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 के बजाय मैं एक "फ़ंक्शन" का उपयोग करना चाहूंगा जो अब किसी कथन द्वारा परिभाषित नहीं है, और मैं बाद में कभी भी उपयोग नहीं करूंगा। फिर सी # हमें इस फ़ंक्शन के अभिव्यक्ति का उपयोग करने की अनुमति देता है। अभिव्यक्ति से मेरा मतलब है "गणितीय" (या कार्यात्मक, प्रोग्राम्स से चिपकने के लिए) इसकी अभिव्यक्ति, उदाहरण के लिए: double x पर मैं doublex*x सहयोगी करूंगा। गणित में आप इसे the "\mapsto" latex symbol का उपयोग करके लिखते हैं। सी # में कार्यात्मक नोटेशन उधार लिया गया है: =>। उदाहरण के लिए:

Func<double, double> thefunctor = ((double x) => x * x); // outer brackets are not 
                  // mandatory 

(double x) => x * x एक expression है। यह एक प्रकार नहीं है, जबकि प्रतिनिधि (सामान्य या नहीं) हैं।

नैतिकता? अंत में, एक प्रतिनिधि सूचकांक (resp। जेनेरिक प्रतिनिधि) क्या होता है, यदि कोई फ़ंक्शन पॉइंटर प्रकार नहीं है (resp। Wrapped + smart + generic function pointer type), हुह? कुछ और ! this और that देखें।

संबंधित मुद्दे