2009-10-29 20 views
12

क्या सी # में एक घटना को दूसरे से कनेक्ट करना संभव है ताकि पहले ईवेंट उत्सर्जित हो जाए? एकमात्र तरीका मैं देख सकता हूं कि एक स्टब फ़ंक्शन बनाना है जो दूसरे ईवेंट को छोड़ देगा और इस फ़ंक्शन में पहली घटना को कनेक्ट करेगा।सी # में घटना के लिए घटना की सदस्यता लें?

class Ui { public event EventHandler OnClick; } 
class Logic { public event EventHandler OnExit; } 
var ui = new Ui(); 
var logic = new Logic(); 
ui.OnClick += logic.OnExit; // Not working. 
ui.OnClick += (a, b) => logic.OnExit; // Not working either :(. 

शायद यह कुछ डेकोरेटर उपलब्ध है या कुछ काला जादू कि ठूंठ कार्यों के बिना श्रृंखला घटनाओं के लिए अनुमति देता है: संकलक घटना या anonymouse कार्य करने के लिए घटना/लैम्ब्डा है कि एक और घटना कॉल करने के लिए घटना कनेक्ट करने के लिए नहीं करना चाहते?

उत्तर

9

आप ऐसा नहीं कर सकते, क्योंकि आप आम तौर पर वस्तु जो इसे जोड़ने और हैंडलर निकाल लिए छोड़कर मालिक बाहर से एक घटना के लिए कुछ नहीं कर सकते। विशेष रूप से, आप मौजूदा पंजीकृत हैंडलर सूचीबद्ध नहीं कर सकते हैं, और आप इसे बढ़ा नहीं सकते हैं। आपके मामले में, घटना को "प्रतिलिपि बनाना" अनिवार्य रूप से छिपाने में एक ही चीज़ है, और आपको इस प्रतिबंध को बाधित करने की अनुमति देगा; इसलिए, इसकी अनुमति नहीं है।

मेरे बारे में और अधिक गहराई से स्पष्टीकरण के लिए this recent answer देखें कि क्यों वे हैं - मैं बस इसे यहां पुनः टाइप करने की तरह महसूस नहीं करता हूं। Ui जुड़े Logic उदाहरण के बारे में पता होना है, और Ui.OnClick.add कार्यान्वयन में Logic.OnClick को ईवेंट हैंडलर्स जोड़ने -

अपने विशेष मामले के लिए, यदि आप दोनों वर्गों के मालिक हैं, वैकल्पिक हल के लिए उन्हें विशेष रूप से सहयोग करना है। बेशक, यह युग्मन शुरू करता है; आप इसे अधिक सामान्य इंटरफेस का उपयोग कर कुछ हद तक कम कर सकते हैं, लेकिन आप इसे पूरी तरह से छुटकारा नहीं पा सकते हैं।

एक साइड नोट के रूप में, OnClick .NET ईवेंट के लिए एक अच्छा नाम नहीं है। सामान्य नामकरण मार्गदर्शिका का कहना है कि यह Click (और OnClick होना चाहिए protected virtual विधि जो इसे उठाती है) का नाम होना चाहिए।

+2

udpate करेगा यह युग्मन युग्मन - यह कहता है कि यह सब^_^है। – grigoryvp

+0

यह ठीक है बिंदु। हैंडलर की सूची उस ऑब्जेक्ट के लिए निजी है जो डिज़ाइन द्वारा ईवेंट का मालिक है। इसका कारण यह है कि अकेले ऑब्जेक्ट को नियंत्रित करना चाहिए कि हैंडलर कब और कैसे आते हैं। यह मूल encapsulation है। यदि आप encapsulation तोड़ना चाहते हैं, तो आपको इसके लिए एक विशेष हैच प्रदान करना होगा, और आपके वर्गों को इसके बारे में पता होना चाहिए - इसलिए युग्मन करना। आप जो पूछ रहे हैं वह वाकई से अलग नहीं है "क्या मैं अपने वर्गों में से किसी एक के निजी क्षेत्र तक पहुंच सकता हूं?"। –

+0

तो मूल रूप से मुझे बस इतना करना है कि सब्सक्रिप्शन कोड को उस दूसरे श्रेणी में ले जाएं जो दूसरे ईवेंट का मालिक हो? :) – grigoryvp

3

आप तर्क के लिए अंतर्निहित घटना को छिपाकर और फिर/निकालने के लिए कॉल को नियंत्रित करके ऐसा कर सकते हैं जिसके लिए UI पैरामीटर की आवश्यकता होती है।

public class UI { 
    public EventHandler OnClick; 
} 
public class Logic { 
    private event EventHandler _onExit; 
    public void AddOnExit(UI ui, EventHandler e) { 
    ui.OnClick += e; 
    _onExit += e; 
    } 
    public void RemoveOnExit(UI ui, EventHandler e) { 
    ui.OnClick -= e; 
    _onExit -= e; 
    } 
} 
+1

अपने उदाहरण में, वह एक ही वस्तु की दो घटनाओं को जोड़ने की कोशिश नहीं कर रहा है - वह दो अलग-अलग वस्तुओं के बीच एक जोड़ी मिलान करने वाली घटनाओं को जोड़ने की कोशिश कर रहा है। –

+0

@ पावेल, आह ठीक है। वही तर्क काम करता है हालांकि दो वस्तुओं के बीच यदि वे अन्यथा जुड़े हुए हैं। लेकिन हाँ, मेरे उदाहरण से थोड़ा अलग, – JaredPar

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