घटनाओं को घोषित करने का पसंदीदा तरीका


14

मैं .NET इवेंट मॉडल की अपनी समझ से काफी खुश हूं। मुझे लगता है कि मैं सिस्टम की एक छोटी सी बारीकियों को गलत समझ सकता हूं।

जब मैंने अपनी कक्षाओं में घटनाओं को डालना शुरू किया तो मैं मानक तरीके का उपयोग करूँगा जैसे:

public event EventHandler<MyEventArgs> MyEvent;

इसका मतलब यह था कि इस कार्यक्रम में सदस्यता लेने वाले किसी भी तरीके की आवश्यकता होगी:

void HandleThatEvent(object sender, MyEventArgs args){...}

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

इसलिए मैंने अपने स्वयं के प्रतिनिधि प्रकार घोषित करने के लिए स्विच किया

public delegate void MyEventHandler(SomeClass argument);

जो अव्यवस्था पर कट गया, लेकिन मुझे एक छोटी सी समस्या के साथ छोड़ दिया जब यह लिखावट में आया:

eventImplmentor.MyEvent += HandleThatEvent;
.
.
.
void HandleThatEvent(/*oh, um, what arguments does it take? Intellisense isn't telling me*/)

इसलिए मुझे प्रतिनिधि की घोषणा पर वापस जाना होगा और देखना होगा और फिर वापस जाकर उन्हें लिखना होगा, या इसे संकलित करना होगा और प्रतीक्षा की जाएगी।

तो अब इसके बजाय, मैं बस का उपयोग कर रहा हूँ Action, Action<T>या जो भी टेम्पलेट फिट बैठता है।

public event Action<SomeClass> MyEvent;

ताकि मैं इस घटना पर मँडरा जाऊँ और बताया जा सके कि यह किन मापदंडों की अपेक्षा करता है।

मेरा सवाल, आखिरकार: क्या सी # में घटनाओं की घोषणा करने के लिए सबसे अच्छा अभ्यास है? क्या मुझे EventHandler<T>रास्ते में वापस जाना चाहिए , या Action<T>स्वीकार्य है?


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

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

जवाबों:


8

सरल, आंतरिक ईवेंट हैंडलिंग के लिए, वे हैं जो बस उपयोग करते हैं Actionया Action<T>, जैसा कि आप प्रस्ताव कर रहे हैं। मैं आंतरिक घटनाओं के लिए, यहां तक ​​कि प्रेषक सहित मानक पैटर्न का उपयोग करने की प्रवृत्ति रखता हूं, क्योंकि आप कभी नहीं जानते हैं कि आप बाद में किसी वर्ग या घटना को कैसे उजागर करना चाहते हैं, और मैं नहीं चाहता कि घटना को ठीक करने के लिए घटना विधि को ठीक करना चाहिए। यह सार्वजनिक है।

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

इसके लायक क्या है, इसके लिए मैंने कुछ समय दिया और एक अलग इवेंट हैंडलिंग पैटर्न के साथ आया: .NET में इवेंट सिग्नेचर - एक मजबूत टाइप्ड 'सेंडर' का उपयोग करना? । यहां लक्ष्य प्रेषक को हटाने का नहीं था, बल्कि इसे TSenderकमजोर रूप से टाइप करने के बजाय उदारतापूर्वक टाइप करने का था System.Object। ये अच्छी तरह काम करता है; हालाँकि, जब आप ऐसा करते हैं तो इंटेलीजेंसी समर्थन खो देते हैं, इसलिए एक दुर्भाग्यपूर्ण व्यापार बंद हो जाता है।

कुल मिलाकर, मैं मानक पैटर्न के साथ रहना चाहूंगा, लेकिन ऐसा करने के संभावित बेहतर तरीकों के बारे में सोचना दिलचस्प है।


मुझे अपने एसओ प्रश्न की ओर इशारा करने के लिए धन्यवाद। यह बहुत दिलचस्प है। मुझे अभी भी समझ नहीं आया कि यह इतना महत्वपूर्ण क्यों है कि प्रेषक अनिवार्य है। अधिकांश समय मैं प्रेषक की परवाह नहीं करता। क्या यह केवल कुछ मनमाना एमएस नियम है?
मैट एलेन

नहीं, निश्चित रूप से आप अपने प्रतिनिधियों को घोषित कर सकते हैं, हालांकि आप पसंद करते हैं। यह हमेशा भेजने वाले को शामिल करने के लिए .NET नीति है, और यह पूरी तरह से एक बुरा विचार नहीं है।
नील

@ नील: मैं समझता हूं कि यह कभी-कभी उपयोगी होता है, लेकिन मुझे हमेशा ऐसा करने की नीति नहीं मिलती है - खासकर जब से एमएस अपने तरीके से घटनाओं को करने की सलाह देता है। घटनाओं के बारे में मुझे जो चीजें पसंद हैं उनमें से एक है, कक्षाओं को डिकॉप करने की क्षमता। अगर मैं ऑब्जेक्ट को शामिल कर रहा हूं, तो यह फिर से युग्मित है। अगर यह सिर्फ एक सीएलएस अनुपालन बात है तो मैं इसके साथ रह सकता हूं।
मैट एलेन

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

हाँ, आप प्रेषक के रूप में 'अशक्त' भेज सकते हैं यदि आप वास्तव में चाहते हैं ... लेकिन, प्रेषक को शामिल करके, घटना हैंडलर स्वयं को सदस्यता समाप्त कर सकता है अगर वह चाहता था। कुल मिलाकर, हालांकि, मैं कहूंगा कि घटना के स्रोत को जानना आमतौर पर बहुत महत्वपूर्ण है।
माइक रोसेनब्लम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.