इवेंट हैंडलर के लिए लैम्ब्डा एक्सप्रेशन का उपयोग करना


114

मेरे पास वर्तमान में एक पृष्ठ है जो निम्नानुसार घोषित किया गया है:

public partial class MyPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //snip
        MyButton.Click += (o, i) =>
        {
            //snip
        }
    }
}

मैंने हाल ही में 1.1 से .NET 3.5 में स्थानांतरित किया है, इसलिए मुझे Page_Load के बाहर इवेंट हैंडलर लिखने की आदत है। मेरा सवाल यह है कि; क्या इसके लिए लैंबडा विधि का उपयोग करते समय मुझे कोई प्रदर्शन कमियां या कमियां दिखनी चाहिए? मैं इसे पसंद करता हूं, क्योंकि यह निश्चित रूप से अधिक संक्षिप्त है, लेकिन मैं इसका उपयोग करने के लिए प्रदर्शन का बलिदान नहीं करना चाहता। धन्यवाद।

जवाबों:


117

कोई प्रदर्शन निहितार्थ नहीं हैं क्योंकि कंपाइलर आपके लैम्ब्डा एक्सप्रेशन को बराबर डेलीगेट में तब्दील कर देगा। लैम्ब्डा एक्सप्रेशंस एक लैंग्वेज फीचर से ज्यादा कुछ नहीं है जो कंपाइलर ठीक उसी कोड में ट्रांसलेट करता है जिसका इस्तेमाल आप काम करने के लिए करते हैं।

संकलक कोड को आपके पास कुछ इस तरह से बदल देगा:

public partial class MyPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //snip
        MyButton.Click += new EventHandler(delegate (Object o, EventArgs a) 
        {
            //snip
        });
    }
}

समझा। तो क्या पेज हैंडल के अंदर इन हैंडलर को रखने और इसके बाहर होने से कोई कमी नहीं है?
क्रिस्टोफर गार्सिया

1
प्रचलित सम्मेलन OnInitविधि संचालकों को घटना में संलग्न करना है लेकिन चूंकि Clickपृष्ठ लोड होने के बाद एक बटन की घटना को उठाया जाएगा क्योंकि यह उदाहरण ठीक है।
एंड्रयू हरे

8
यह ध्यान रखना महत्वपूर्ण है कि प्रतिनिधि के संदर्भ को बनाए रखने के बिना, आप घटना से सदस्यता समाप्त नहीं कर सकते।
स्नार्फ

3
"सटीक समान कोड" थोड़ा भ्रामक है; कम से कम जब एन्कोडिंग विधि से स्थानीय चर का संदर्भ देते हैं, तो लैम्ब्डा अभिव्यक्तियों को तरीकों में अनुवाद नहीं किया जाता है और एक करीबी वस्तु की तरह कुछ होता है जो स्थानीय चर के वर्तमान मूल्यों को संग्रहीत करता है।
या मैपर

66

प्रदर्शन-वार यह एक नामित विधि के समान है। बड़ी समस्या यह है कि जब आप निम्न कार्य करते हैं:

MyButton.Click -= (o, i) => 
{ 
    //snip 
} 

यह शायद एक अलग मेमने को हटाने की कोशिश करेगा, मूल को वहीं छोड़ देगा। तो सबक यह है कि यह तब तक ठीक है जब तक आप हैंडलर को हटाने में सक्षम होना चाहते हैं।


3
"यह शायद करने की कोशिश करेंगे ..."? क्या यह कभी भी ऐसी स्थिति में सही हैंडलर को हटा देगा ?
या मैपर

1
@ORMapper: यदि लैम्ब्डा एक वैरिएबल को पकड़ता है, तो यह सही हैंडलर को हटा नहीं सकता है। अन्य परिस्थितियों में, यह संकलक तक है।
गाबे

वास्तव में? दिलचस्प है - इसलिए, यदि मैं दो अनाम कार्यों को पंजीकृत करता हूं जो समान दिखते हैं (व्लॉग में एक खाली बॉडी है), और फिर मैं -=किसी अन्य अनाम फ़ंक्शन का उपयोग नहीं करता हूं ( जो कि एक खाली निकाय है), यह अनिवार्य रूप से अपरिभाषित है जो दो ईवेंट हैंडलर्स में से एक है हटाया जा सकता है, या उनमें से किसी को भी हटा दिया जाएगा?
या मैपर

4
@ शेयरर: हाँ। संकलक को अनुमति दी जाती है (लेकिन उसके पास नहीं है) समान प्रतिनिधि बनाते हैं यदि उनके पास समान शब्दार्थ है (कोड समान नहीं होना चाहिए, लेकिन उन्हें एक ही काम करना होगा) और समान चर उदाहरणों को कैप्चर करें (न कि केवल समान चर, लेकिन उन चर के समान उदाहरण)। सभी विवरणों के लिए सी # कल्पना के खंड 7.10.8 (प्रतिनिधि समानता ऑपरेटरों) देखें।
गब

12
यदि आप वास्तव में लैम्ब्डा का उपयोग करना चाहते हैं, लेकिन घटना को दूर करने की आवश्यकता है, तो आप हमेशा किसी स्थानीय चर / क्षेत्र में ऑब्जेक्ट को पकड़ कर रख सकते हैं, फिर उसे हटा सकते हैं, जैसेvar event = (o, e) => doSomething(); handler += event; doSomethingElse(); handler -= event;
वाई हा ली

44
EventHandler handler = (s, e) => MessageBox.Show("Woho");

button.Click += handler;
button.Click -= handler;

1
बहुत उपयोगी जानकारी, हालांकि यह विषय से दूर है (सवाल प्रदर्शन के बारे में है)।
स्टीफन गौरिचोन

4
मेमोरी उपयोग के बाद से ऑफ-टॉपिक बिल्कुल नहीं है, जिससे प्रदर्शन में गिरावट आ सकती है।
व्लादिस

3
एक हैंडलर में खुद को निकालना भी मददगार हो सकता है:c# EventHandler handler = null; handler = (s, e) => { MessageBox.Show("Woho"); button.Click -= handler;}
व्लादिस

2

कोई प्रदर्शन निहितार्थ नहीं है कि मैं इसके बारे में जानता हूं या कभी भी भाग गया हूं, जहां तक ​​मुझे इसकी "सिंटैक्टिक शुगर" पता है और एक ही चीज के लिए संकलित करता है जैसे कि प्रतिनिधि सिंटैक्स का उपयोग करना, आदि।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.