2013-03-05 10 views
10

मेरा प्रश्न निम्न कोड में विस्तृत है करने के लिए एक मल्टीकास्ट प्रतिनिधि का उपयोग करना - कारण मैं इस पूछ रहा हूँ है कि मैं प्रतिनिधियों के साथ प्रयोग कर रहा हूँ:श्रृंखला कार्यों

//create the delegate   
delegate int del(int x); 

class Program { 


    static void Main(string[] args) { 

     Program p; 
     p = new Program(); 

     del d = p.a; 
     d += p.b; 
     d += p.c; 
     d += p.d; 
     d += p.e; 
     Console.WriteLine(d(10)); //<<was hoping it would be 10+2+3+4+5+6 

     Console.WriteLine("press [enter] to exit"); 
     Console.ReadLine(); 
    } 

    private int a(int x) { Console.WriteLine("a is called"); return x + 2; } 
    private int b(int x) { Console.WriteLine("b is called"); return x + 3; } 
    private int c(int x) { Console.WriteLine("c is called"); return x + 4; } 
    private int d(int x) { Console.WriteLine("d is called"); return x + 5; } 
    private int e(int x) { Console.WriteLine("e is called"); return x + 6; } 

} 

16 लौटा दिया जाता है ....

enter image description here

सभी कार्यों आग, विभिन्न संदेश के रूप में "एक कहा जाता है" आदि सभी console को मुद्रित करने के लेकिन केवल राशि पिछले समारोह e से लौटे दिया जाता है - मैं बक में यह सोचते हैं रहा हूँ का मैदान वे लौट रहे हैं लेकिन फिर अधिलेखित?

+0

इस तरह के रिकर्सन प्राप्त करने के लिए, मुझे लगता है कि आपको पिछले प्रतिनिधि को पैरामीटर के रूप में पास करना होगा। अन्यथा, आप केवल 10 + 6 = 16. –

+0

@ डेविन ट्रायॉन जोड़ रहे हैं जो वास्तव में रिकर्सन नहीं है। कोई फ़ंक्शन स्वयं कॉल नहीं कर रहा है; यह सिर्फ कार्यों की श्रृंखला है। – Servy

+0

@ सर्वी आह हाँ, "नेस्टेड" कार्यों की तरह अधिक? क्या इसके लिए कोई कार्यात्मक भाषा नाम है? –

उत्तर

14

आप में d की तरह एक बहुस्त्र्पीय प्रतिनिधि है जब आपके प्रश्न, वापसी मूल्य अंतिमd की आमंत्रण सूची की विधि से वापसी मूल्य है।

सामान्यतः, मल्टीकास्ट प्रतिनिधियों के लिए, वापसी प्रकार void का उपयोग करना सबसे स्वाभाविक है।

कंपाइलर को यह अनुमान लगाने का कोई मौका नहीं था कि आप 10+2+3+4+5+6 की उम्मीद कर रहे थे। आपने इसे कहीं भी निर्दिष्ट नहीं किया है।

आप में अपने प्रतिनिधि प्रकार बदल सकता है:

delegate void del(int xToAdd, ref int sum); 

फिर अपने विधि a, उदाहरण के लिए, इस तरह दिखना चाहिए:

private void a(int x, ref int sum) { Console.WriteLine("a is called"); sum += x + 2; } 

बहुस्त्र्पीय प्रतिनिधि उदाहरण d तो इस तरह कहा जा सकता है :

int sum = 0; 
d(10, ref sum); 
Console.WriteLine(sum); 

मुझे उम्मीद है कि वह LPS।

+1

एक अपेक्षाकृत आसान दृष्टिकोण +1 – whytheq

8

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

मैं आपको किसी घटना का उपयोग करने से अत्यधिक हतोत्साहित करता हूं (आप इस प्रतिनिधि का इलाज कर रहे हैं जैसे कि यह एक घटना है) जिसमें वापसी मूल्य है। व्यवहार वस्तुतः वांछनीय नहीं है। यदि आप वापसी मूल्य चाहते हैं तो यह सुनिश्चित करने के लिए यह समझ में आता है कि आपका प्रतिनिधि हमेशा एक समारोह में मैप किया जाता है, और नहीं, कम नहीं।

वास्तव में वांछित परिणाम पैदा करने के लिए के रूप में, जबकि वहाँ दृष्टिकोण के एक नंबर रहे हैं, तो आप बेहतर प्रतिनिधियों की एक और अधिक परंपरागत संग्रह के साथ ऐसा दिखाई देगा:

List<Func<int, int>> functions = new List<Func<int, int>>(); 
//populate 

int result = functions.Aggregate(10, (total, func) => func(total)); 
+0

+1 वापसी मूल्य के बारे में अच्छी सूचना –

+1

आमंत्रण सूची में विधियों को क्रम में बुलाया जाता है, उन अंतिम कॉलों का वापसी मूल्य उपयोग किया जाता है (इसे यादृच्छिक रूप से नहीं चुना जाता है), आप ** ** उस पर भरोसा कर सकते हैं। सी # spec उद्धृत करने के लिए: _ "एक प्रतिनिधि उदाहरण का निमंत्रण जिसका आमंत्रण सूची में कई प्रविष्टियां शामिल होती हैं, इनवॉइस सूची में प्रत्येक विधि को क्रमशः, क्रमशः, आविष्कार से प्राप्त करती है।" _ और आगे वापसी मूल्य _ "आमंत्रण से आएगा सूची में अंतिम प्रतिनिधि का। "_ समान पैराग्राफ भी गारंटी देता है कि 'रेफरी पैरामीटर का उपयोग किया जा सकता है, जैसा कि मैंने अपने उत्तर में किया है। –

+0

@JeppeStigNielsen हां, मुझे पता है कि। यह इस तथ्य को नहीं बदलेगा कि इस पर भरोसा करना बहुत बुरा अभ्यास है, क्योंकि यह अपरिभाषित नहीं है और बदल सकता है, लेकिन क्योंकि यह अच्छी तरह से ज्ञात नहीं है, और व्यवहार नहीं है कि कोड के पाठक * उम्मीद * को अच्छी तरह से परिभाषित करने की उम्मीद करेंगे। बहुसंख्यक वातावरण में तर्क करना भी मुश्किल हो जाता है, जो इस मनोरंजक घटनाओं से निपटने पर विशेष रूप से आम है। मेरा जवाब इस बारे में स्पष्ट है; यह वास्तव में * संभव * है, यह सिर्फ एक बहुत बुरा विचार है। – Servy

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