2010-03-19 20 views
11

इसलिए मैंने एमएसडीएन और स्टैक ओवरफ़्लो पढ़ा। मैं समझता हूं कि एक्शन प्रतिनिधि सामान्य रूप से क्या करता है लेकिन यह कोई फर्क नहीं पड़ता कि मैं कितने उदाहरण करता हूं। आम तौर पर, प्रतिनिधियों के विचार के लिए भी यही होता है। तो ये रहा मेरा प्रश्न। जब आपके पास ऐसा कोई कार्य होता है:कृपया .NET प्रतिनिधि बताएं

public GetCustomers(Action<IEnumerable<Customer>,Exception> callBack) 
{ 
} 

यह क्या है, और मुझे इसे क्या पास करना चाहिए?

उत्तर

9

यह एक समारोह है कि IEnumerable लेता है और अपवाद और शून्य रिटर्न की उम्मीद है।

void SendExceptionToCustomers(IEnumerable<Customer> customers, Exception ex) { 
    foreach(var customer in customers) 
     customer.SendMessage(ex.Message); 
} 

GetCustomers(SendExceptionToCustomers); 

btw, GetCustomers इस कार्य के लिए एक भयानक नाम की तरह लगता है - यह एक कार्रवाई के लिए पूछ रहा है, इसलिए इसकी अधिक DoSomethingToCustomers

तरह

जवाब में संपादित टिप्पणी करने के लिए


ठीक है समझ में आता है, तो अब GetCustomer फ़ंक्शन होने से भी परेशान क्यों है? क्या मैं अपने काम के साथ वही काम नहीं कर सकता अगर मैं इसे सिर्फ GetCustomer का नाम बदलूं?

ठीक है, यहां क्या हो रहा है कॉलर कुछ क्रिया निर्दिष्ट कर सकता है।मान लीजिए GetCustomers इस तरह कार्यान्वित किया जाता है:

public void GetCustomers(Action<Enumerable<Customer>, Exception> handleError) { 
    Customer[] customerlist = GetCustomersFromDatabase(); 
    try { 
     foreach(var c in customerList) 
      c.ProcessSomething() 
    } catch (Exception e) { 
     handleError(customerList, e); 
    } 
} 

तो आप एक कमांडलाइन कार्यक्रम पर कहीं से Getcustomers कहते हैं, और पारित यह

GetCustomers((list, exception) => { 
    Console.WriteLine("Encountered error processing the following customers"); 
    foreach(var customer in list) Console.WriteLine(customer.Name); 
    Console.WriteLine(exception.Message); 
}); 

जब आप एक दूरस्थ अनुप्रयोग से GetCustomers कह सकते हैं, उदाहरण के लिए कर सकता है, और पारित यह

Getcustomers((list, exception) => { 
    // code that emails me the exception message and customer list 
}) 


इसके अलावा, Slak की टिप्पणी प्रतिनिधि पैरामीटर के लिए एक और कारण पता चलता है - GetCusto mers ग्राहकों को पुनः प्राप्त करता है, लेकिन असीमित रूप से। जब भी यह ग्राहकों को पुनर्प्राप्त किया जाता है, तो यह एक ऐसा अपवाद होता है जब आप इसे किसी भी अपवाद के साथ प्राप्त करते हैं, तो आप इसे ग्राहक सूची या अपवाद के साथ देते हैं।

public void DoSomeStuffWithCustomers(
    IEnumerable<Customer> customers, Exception exception) 
{  
} 

आप इस तरह GetCustomers विधि कहेंगे:

+0

में देख सकते हैं बुरे नाम से सहमत हैं। –

+0

ऐसा लगता है कि कॉलबैक उन ग्राहकों को प्राप्त करता है जो ग्राहकों को असीमित रूप से लोड करने के बाद लोड (या अपवाद) प्राप्त होते हैं। – SLaks

+2

मुझे ज्यादातर समय ग्राहकों को कुछ करना अच्छा लगेगा, खासकर जब वे परेशान हों। –

3

एक प्रतिनिधि एक वर्ग है जो एक या अधिक कार्यों को इंगित करता है। एक प्रतिनिधि उदाहरण का आह्वान किया जा सकता है, जो उस कार्य को कॉल करेगा जिसे वह इंगित करता है।

आपके मामले में, GetCustomers फ़ंक्शन एक पैरामीटर के रूप में एक दूसरा कार्य करता है।

दूसरा समारोह प्रकार IEnumerable<Customer> और Exception के दो पैरामीटर नहीं होना चाहिए।

GetCustomers पर कॉल करने के लिए, आपको कॉल करने के लिए एक दूसरा फ़ंक्शन बनाने की आवश्यकता है, फिर उसे दूसरे फ़ंक्शन वाले प्रतिनिधि को पास करें।

उदाहरण के लिए:

static void GetCustomersCallback(IEnumerable<Customer> customers, Exception ex) { 
    //Do something... 
} 

//Elsewhere: 
GetCustomers(new Action<IEnumerable<Customer>,Exception>(GetCustomersCallback)); 

इस कॉल के लिए एक नया प्रतिनिधि उदाहरण है कि GetCustomersCallback समारोह को इंगित करता है बनाता है, और GetCustomers कार्य करने के लिए है कि प्रतिनिधि गुजरता है। GetCustomers ग्राहक लोड होने के बाद कॉलबैक को संभवतः कॉल करेंगे, और लोड किए गए ग्राहकों को पैरामीटर के रूप में पास कर देगा।
तुम भी प्रतिनिधि इन्स्टेन्शियशन छोड़ देते हैं और समारोह सीधे पारित कर सकते हैं:

GetCustomers(GetCustomersCallback); 
+0

मुझे यह मानना ​​नहीं है कि यह एक वर्ग है, हालांकि यह एक अलग प्रकार का संदर्भ प्रकार है: http://msdn.microsoft.com/en-us/library/900fyy8e(VS.71).aspx –

+0

@ निक: 'सिस्टम। डिलीगेट' एक वर्ग है; आप इसे रिफ्लेक्टर – SLaks

0

आप इसे एक शून्य विधि है कि एक IEnumerable और पैरामीटर के रूप में एक अपवाद लेता पास होता ...

आप इस विधि है कहो

GetCustomers(DoSomeStuffWithCustomers); 
2

आप एक लैम्ब्डा

GetCustomers((cust, ex) => { 
    //do something here} 
); 
के साथ कॉल कर सकते हैं
1

यह सी के फ़ंक्शन पॉइंटर्स का एक अपडेटेड संस्करण है, जिसमें किसी ऑब्जेक्ट इंस्टेंस से बंधे होने की संभावना है, यदि यह एक गैर स्थैतिक ऑब्जेक्ट विधि पॉइंटर है (सी ++ उन्हें विधि पॉइंटर्स कहा जाता है जब उन्होंने ऑब्जेक्ट्स और फ़ंक्शन पॉइंटर्स को एक साथ जोड़ा)।

प्रकार हस्ताक्षर सी # की जेनेरिक सुविधाओं का उपयोग करके जेनेरिक बनाया जा सकता है।

सभी जेनेरिक सामान केवल हस्ताक्षर को templatizing है।

नाम प्रतिनिधि खराब चुना जाता है (जब तक आप हमारे क्षुधा के सभी के बारे में सोच चौखटे द्वारा संचालित किया जा रहा)। क्योंकि उपयोग हमेशा "प्रतिनिधि" नहीं होता है। कई बार यह कोड है जिसे आपने कुछ जिम्मेदारी सौंपी है (एक पुनरावर्तक, कहें) जो आपके द्वारा पहले भेजे गए "प्रतिनिधि" को बुलाता है। यही कारण है कि आप अक्सर कॉलबैक शब्द देखते हैं।

कॉलबैक परंपरागत रूप से आपके एप्लिकेशन कोड के लिए ढांचे के बीच में कॉल किया जाना चाहिए या जब कोई विशेष घटना होती है। यह आपको अन्य कोड के बीच में अपना कोड प्राप्त करने की अनुमति देता है - वास्तव में, यह केवल थ्रेड के भीतर ही एकमात्र तरीका है।

जाहिर है, .NET ईवेंट हैंडलर उचित समय पर ढांचे द्वारा प्रतिनिधियों को बुला रहे हैं, और आप अपने कार्यों में प्रतिनिधियों को स्वीकार कर सकते हैं और उन्हें उचित रूप से कॉल कर सकते हैं ताकि आप अपना कोड कुछ सामान्य/पुन: प्रयोज्य/संगठित कर सकें।

0

उन्होंने मुझे से बाहर नरक उलझन में जब तक मैं पढ़ें:

  1. एंड्रयू ट्रोलसन के Head First Design Patterns

में Pro C# 2008 and the .Net 3.5 Platform

  • पर्यवेक्षक पैटर्न पर अध्याय में उनमें से स्पष्टीकरण दूसरी पुस्तक के बारे में है कि जावा, और प्रतिनिधियों का जिक्र नहीं करता है, लेकिन यह अच्छी तरह से बताता है कि एक समस्या प्रतिनिधि हल करने में मदद करते हैं: कक्षाओं के बीच संचार।

  • 2
    +0

    क्या आपका मतलब था: http://www.sellsbrothers.com/writing/delegates.htm? –

    +0

    @Kees - yup! ऐसा लगता है कि यूआरएल बदल गया है। इसे पकड़ने के लिए धन्यवाद। अपडेट किया गया। – PatrickSteele

    1

    आप? फंक्शन पॉइंटर्स

    +1

    न केवल फ़ंक्शन पॉइंटर्स। फ़ंक्शन पॉइंटर और कुछ डेटा का संयोजन जो कि उस फ़ंक्शन के उपयोग के लिए उपयुक्त प्रकार के होने की गारंटी है। – supercat

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