2009-06-10 7 views
33

में अज्ञात प्रतिनिधियों मैं एक प्रतिनिधि के लिए केवल एक ही कॉल के लिए एक प्रतिनिधि को परिभाषित करने और नामकरण करने से थक गया अकेला नहीं हो सकता जिसके लिए एक प्रतिनिधि की आवश्यकता होती है। उदाहरण के लिए, मैं संभवतः अन्य धागे से एक के रूप में .refresh() कॉल करने के लिए चाहता था, इसलिए मैं इस कोड लिखा है:सी #

private void RefreshForm() 
{ 
    if (InvokeRequired) 
     Invoke(new InvokeDelegate(Refresh)); 
    else 
     Refresh(); 
} 

मैं भी यकीन है कि मैं करने के लिए, मैं सिर्फ पर्याप्त पढ़ा है कि डरने की नहीं कर रहा हूँ यह कुछ बाद के चरण में काम नहीं करेगा।
InvokeDelegate वास्तव में किसी अन्य फ़ाइल में घोषित किया गया है, लेकिन क्या मैं वास्तव में इस के लिए समर्पित एक संपूर्ण प्रतिनिधि की आवश्यकता है? क्या कोई सामान्य प्रतिनिधि नहीं हैं?
मेरा मतलब है, उदाहरण के लिए, एक पेन क्लास है, लेकिन पेन भी हैं। पेन-ऑफ-पसंद इसलिए आपको पूरी चीज को रीमेक करने की ज़रूरत नहीं है। यह वही नहीं है, लेकिन मुझे आशा है कि आप समझेंगे कि मेरा क्या मतलब है।

+1

सी # में "अज्ञात प्रतिनिधि" जैसी कोई चीज़ नहीं है। प्रतिनिधि हैं (जैसे आप उपयोग कर रहे हैं) और अनाम विधियां (जो केवल एक प्रतिनिधि के माध्यम से सुलभ हैं)। – Lucas

+3

मुझे लगता है कि सी # spec शब्द "अज्ञात विधि" का उपयोग करता है क्योंकि यह सही तरीका होगा। हालांकि, इस शब्द का उपयोग बहुत से लोगों द्वारा पैरामीटर के रूप में अज्ञात विधि के साथ तत्काल एक प्रतिनिधि का मतलब है। इसलिए, उनका मतलब एक ही बात है, लेकिन जिस संदर्भ में कोई व्यक्ति दूसरे शब्द पर एक शब्द का उपयोग कर सकता है, उस पर अक्सर निर्भर करता है कि कोई प्रतिनिधि असाइनमेंट होता है या यदि अज्ञात विधि सीधे किसी अन्य विधि से पारित की जा रही है या नहीं। मैं इसके विपरीत किसी भी तर्क का स्वागत करता हूं। –

उत्तर

52

हां। .NET 3.5 में आप Func और Action प्रतिनिधियों का उपयोग कर सकते हैं। फनक प्रतिनिधि एक मूल्य वापस करते हैं, जबकि एक्शन प्रतिनिधि शून्य लौटते हैं। यहाँ प्रकार के नाम की तरह लग रहे हैं क्या है:

System.Func<TReturn> // (no arg, with return value) 
System.Func<T, TReturn> // (1 arg, with return value) 
System.Func<T1, T2, TReturn> // (2 arg, with return value) 
System.Func<T1, T2, T3, TReturn> // (3 arg, with return value) 
System.Func<T1, T2, T3, T4, TReturn> // (4 arg, with return value) 

System.Action // (no arg, no return value) 
System.Action<T> // (1 arg, no return value) 
System.Action<T1, T2> // (2 arg, no return value) 
System.Action<T1, T2, T3> // (3 arg, no return value) 
System.Action<T1, T2, T3, T4> // (4 arg, no return value) 

मैं नहीं जानता कि क्यों वे 4 आर्ग प्रत्येक पर रोका, लेकिन यह हमेशा मेरे लिए काफी किया गया है।

+2

4 एक ठोस नियम नहीं है, लेकिन अतीत है कि आपको कम से कम कुछ तरीकों से संयोजन मानकों पर विचार करना चाहिए। –

+1

जब मैं कुछ पुराने .NET कोड को 3.5 पर पोर्ट कर रहा हूं और मुझे एक प्रतिनिधि दिखाई देता है तो मैं उन्हें फनक या एक्शन के लिए बाहर कर देता हूं। – RichardOD

+10

ढांचे के अगले संस्करण में चार से अधिक पैरामीटर के Func और Action शामिल होंगे। –

4

लघु संस्करण:

Invoke((MethodInvoker)delegate { Refresh(); }); 

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

private void SetControlText(Control ctl, string text) 
{ 
    Invoke((MethodInvoker)delegate { ctl.Text = text; }); 
} 
+0

आप इसे किसी मौजूदा प्रतिनिधि प्रकार में डालने के लिए सिर्फ एक अज्ञात प्रतिनिधि क्यों बनायेंगे? आपको सीधे प्रतिनिधि प्रकार का उपयोग करना चाहिए। –

+2

@ ब्रायन: आपका मतलब इस तरह है: आमंत्रित करें (नया MethodInvoker (प्रतिनिधि {ctl.Text = text;})); ? जहां तक ​​मैं देख सकता हूं कि उपरोक्त मेरे कोड के रूप में सटीक एक ही आईएल कोड उत्पन्न करता है, इसलिए यह व्यक्तिगत स्वाद के लिए नीचे है, मुझे लगता है। –

+0

MethodInvoker और Action के बीच क्या अंतर है? इसके अलावा, मैं InvokeRequired की जांच कर रहा हूं क्योंकि यह एक बेहतर अभ्यास प्रतीत होता है, उदाहरण के लिए, तेज़। – Nefzen

26

कार्रवाई प्रतिनिधि आप इस्तेमाल कर सकते हैं नहीं है है, तो जैसे:

private void RefreshForm() 
{ 
    if (InvokeRequired) Invoke(new Action(Refresh)); 
    else Refresh(); 
} 

या, लैम्ब्डा सिंटैक्स के साथ:

private void RefreshForm() 
{ 
    if (InvokeRequired) Invoke((Action)(() => Refresh())); 
    else Refresh(); 
} 

अंत में वहाँ गुमनाम प्रतिनिधि वाक्य रचना:

+०१२३५१६४१०६
private void RefreshForm() 
{ 
    if (InvokeRequired) Invoke((Action)(delegate { Refresh(); })); 
    else Refresh(); 
} 
+2

विचित्र रूप से, दूसरा और तीसरा वाक्यविन्यास यह नहीं कहता कि यह इसे सिस्टम में परिवर्तित नहीं कर सकता है। प्रतिनिधि बनाएं क्योंकि यह एक प्रतिनिधि प्रकार नहीं है। हालांकि, कार्रवाई निश्चित रूप से मैं चाहता हूं कि मैं चाहता हूं। – Nefzen

+1

अज्ञात प्रतिनिधियों को इस तरह से आमंत्रित करने के लिए पारित नहीं किया जा सकता क्योंकि वे टाइप प्रतिनिधि नहीं हैं। जो आपने यहां लिखा है वह संकलित भी नहीं करता है। –

+1

हे, पोस्टिंग से पहले जांचने के लिए मुझे यही मिलता है। मैं एएसपी ठीक कर दूंगा। –

1

हां, सामान्य प्रतिनिधि हैं। Action<T1, T2...> एक सामान्य प्रतिनिधि है जो कुछ पैरामीटर लेता है और कोई मूल्य नहीं देता है, और Func<T1, T2...R> एक सामान्य प्रतिनिधि है जो कुछ पैरामीटर लेता है और एक मूल्य देता है।

2

क्या मुझे वास्तव में इसके लिए समर्पित एक संपूर्ण प्रतिनिधि की आवश्यकता है? कोई सामान्य प्रतिनिधि नहीं हैं?

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

public delegate int UpdateDelegate(int userID, string city, string, state, string zip); 

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

Func<T> 
Func<T, U> 
Func<T, U, V> 
Func<T, U, V, W> 
Action, Action<T> 
Action<T, U> 
Action<T, U, V> 
Action<T, U, V, W> 

केवल Action और Action में मौजूद है:

हालांकि, अगर आप Intellisense त्याग कोई आपत्ति नहीं है, वहाँ पहले से ही जो तदर्थ प्रतिनिधियों के रूप में इस्तेमाल किया जा सकता सिस्टम नाम स्थान में definined प्रतिनिधियों का एक वर्ग है .NET 2.0, लेकिन शेष प्रतिनिधियों के साथ एक सहायक वर्ग घोषित करने के लिए यह इतना आसान है कि आपको इस तरह के विविध विज्ञापन कार्यों के लिए जरूरी है।

8

इस विशिष्ट मामले में आप ऐसा करने के लिए (और चाहिए) MethodInvoker का उपयोग कर सकते हैं ... यही कारण है कि यह मौजूद है।

if (InvokeRequired) 
    Invoke(new MethodInvoker(Refresh)); 
else 
    Refresh(); 

आप कुछ और कर रहे थे, तो आप, के रूप में दूसरों का जवाब दे दिया उपयोग समारोह < टी, ... > या कार्रवाई < टी, ... > अगर वे आपके उपयोग के मामले फिट सकता।

+1

यह .NET 2.0 के लिए सबसे अच्छा समाधान है –