2009-07-07 17 views
19

सी # using कथन है, खासकर आईडीस्पोजेबल ऑब्जेक्ट्स के लिए। संभवतः, using कथन में निर्दिष्ट किसी ऑब्जेक्ट में कुछ प्रकार का संसाधन होगा जो निर्धारित रूप से मुक्त किया जाना चाहिए।खराब अभ्यास? सी # के उपयोग कथन का गैर-कैनन उपयोग

हालांकि, मुझे लगता है कि प्रोग्रामिंग में कई डिज़ाइन हैं जिनमें एक एकल, निश्चित शुरुआत और अंत है, लेकिन आंतरिक भाषा समर्थन की कमी है। using निर्माण कम से कम, स्पष्ट रूप से और स्वाभाविक रूप से ऐसे डिज़ाइन या ऑपरेशन के दायरे को हाइलाइट करने के लिए कोड संपादक की अंतर्निहित सुविधाओं का उपयोग करने का अवसर प्रदान करता है।

क्या मैं मन में है आपरेशन के प्रकार है कि अक्सर, एक BeginXXX() और EndXXX() विधि के साथ शुरू होता है, हालांकि इस तरह के एक अतुल्यकालिक कोड निष्पादन शामिल है कि एक "शुरू" और "शामिल हों" के रूप में विभिन्न जायके, के बहुत सारे हैं।

इस बेवकूफ उदाहरण को लें।

webDataOperation.Start(); 
GetContentFromHardDrive(); 
webDataOperation.Join(); 
// Perform operation that requires data from both sources 

क्या होगा अगर, बजाय, प्रारंभ विधि एक वस्तु जिसका IDisposable.Dispose विधि में शामिल होने के कार्रवाई निष्पादित लौट आए।

using(webDataOperation.Start()) { 
    GetContentFromHardDrive(); 
} 
// Perform operation that requires data from both sources 

या, बेहतर अभी तक, क्या मैं विशेष रूप से मन में था: मैं एक उद्देश्य यह है कि अति विशिष्ट ग्राफिक्स blitting करता है और एक Begin() और End() विधि (एक डिजाइन भी DirectX में वर्तमान और XNA) है है। इसके बजाय ...

using(blitter.BlitOperation()) { 
    // Do work 
} 
// Use result 

यह अधिक प्राकृतिक और पठनीय हो रहा है, लेकिन यह अनुचित है, के रूप में यह IDisposable इंटरफेस और अनायास ही उद्देश्यों के लिए using कथन का उपयोग करती दिख रहे हैं? दूसरे शब्दों में, क्या यह एक गैर-सहज ज्ञान युक्त तरीके में ऑपरेटर को वर्लोड करने के बराबर होगा?

+0

क्यों न केवल शुरुआत में {शुरुआत में}} का उपयोग करें? यह उपयोग करने के दुरुपयोग के बिना गुंजाइश प्रदान करता है। – cja

उत्तर

20

यह एक पूरी तरह स्वीकार्य अभ्यास है। इन्हें फैक्टर प्रकार कहा जाता है, और Framework Design Guidelines बस ऐसा करने की सिफारिश करता है।

मूल रूप से, यदि प्रकार विशिष्ट जीवनकाल के साथ एक ऑपरेशन को लपेटता है, तो IDISposable का उपयोग करके और उपयोग कथन पर विचार करने के लिए एक उचित बात बन जाती है।

मैंने वास्तव में लगभग this specific topic here ब्लॉग किया है।

+0

अच्छा खोज, लेकिन क्या आपके तर्क के लिए कोई तर्क है? लेख इसकी सिफारिश करता है, लेकिन चर्चा क्यों नहीं करता है। – snarf

+0

ऐसा इसलिए है क्योंकि यह गारंटी देता है कि एंडऑपरेशन() को हमेशा (निपटान के माध्यम से) कहा जाता है (0) –

+1

@Snarfblam: असल में, ऑपरेशन स्वयं संसाधन के रूप में कार्य करता है जिसे सफाई की आवश्यकता होती है। अधिक जानकारी के लिए मेरे ब्लॉग पोस्ट को पढ़ें - यह दूसरा लिंक है। मैं यहां से ज्यादा न्यायसंगतता डालता हूं। –

2

मुझे लगता है कि आपको इसके लिए क्या उद्देश्य है, इसके लिए IDISposable का उपयोग करना चाहिए, और कुछ भी नहीं। यही है, अगर रखरखाव आपके लिए मायने रखता है।

+1

जॉन: फ़ैक्टर प्रकार पर फ़्रेमवर्क डिज़ाइन दिशानिर्देश देखें: http://blogs.msdn.com/brada/archive/2009/02/23/framework-design-guidelines-factored-types.aspx - अब यह अनुशंसित है उन्हें संभालने के लिए दृष्टिकोण। –

+0

यह प्रभाव को कैसे बनाए रखता है? और क्या यह एकमात्र कारण है कि आप कैनन के सख्त अनुपालन की अनुशंसा करते हैं? – snarf

+0

यह समझने के लिए कि क्या हो रहा है, यह अन्य डेवलपर्स की क्षमता को प्रभावित करता है। सिफारिश के लिए मेरा कारण इस तथ्य में शामिल है कि सामान्य कारणों से लोगों को IDISposable का उपयोग करने के लिए पर्याप्त कठिन है - हमें अतिरिक्त लोगों की आवश्यकता नहीं है। –

0

मैं कहूंगा कि यह स्वीकार्य है - असल में, मैंने इसे कुछ परियोजनाओं में उपयोग किया है जहां मैं एक विशिष्ट कोड ब्लॉक के अंत में एक क्रिया ट्रिगर करना चाहता था।

http://blogs.msdn.com/wesdyer/archive/2007/02/23/linq-to-ascii-art.aspx

class ActionDisposable: IDisposable 
{ 
    Action action; 

    public ActionDisposable(Action action) 
    { 
     this.action = action; 
    } 

    #region IDisposable Members 

    public void Dispose() 
    { 
     this.action(); 
    } 

    #endregion 
} 
: -

वेस Deyer उसकी LINQ में इसका इस्तेमाल किया कला कार्यक्रम ASCII करने के लिए, वह यह कार्रवाई डिस्पोजेबल (: डी मैं अपने फैसले पर भरोसा था वेस सी # संकलक टीम पर काम करता है) कहा जाता है

अब आप एक समारोह से लौट सकते हैं कि, और कुछ इस तरह करते हैं:

using(ExtendedConsoleWriter.Indent()) 
{ 
    ExtendedConsoleWriter.Write("This is more indented"); 
} 

ExtendedConsoleWriter.Write("This is less indented"); 
+1

वाह, यह उपयोग कथन का एक स्पष्ट दुरुपयोग है। मुझे नहीं पता होगा कि वह कोड विस्तारित कंसोलवाइटर कोड खोलने के बिना क्या करने का प्रयास कर रहा था। यदि कोड के आस-पास बढ़ने और घटाने के लिए कॉल करने के लिए कॉल किया गया था, तो कोई सवाल नहीं होगा। –

+0

मैं इसके लिए "उपयोग" का उपयोग नहीं करता, लेकिन, मान लीजिए कि एक समान कीवर्ड और संबंधित इंटरफ़ेस जैसे "साथ" थे: (लेखक.इंडेंट()) {सामान; }, यह एक दृढ़ निर्माण होगा। – snarf

+3

यिक्स, रयान। यह एक त्वरित लिखित उदाहरण था। मैं सहमत हूं, मैं इसे बढ़ाना चाहता हूं इंडेंट - जिस स्थिति में मैं इसे "उपयोग कथन का एक झटकेदार दुरुपयोग" नहीं कहूंगा। इस तरह की अवधारणा को पूरे .NET में लेन-देन के लेन-देन में देखा जा सकता है - ऐसा लगता है कि आप minutae पर थोड़ा कठोर रूप से नीचे आ रहे हैं। – Charles

5

यह एक आम पैटर्न है, लेकिन व्यक्तिगत रूप से, मुझे विश्वास है कि आईडी का दुरुपयोग करने के लिए कोई बहाना नहीं है कि इस तरह के इस्पोजेबल जब आप अज्ञात प्रतिनिधियों और/या लैम्बदास के साथ एक और अधिक स्पष्ट तरीके से एक ही प्रभाव प्राप्त कर सकते हैं; यानी .:

blitter.BlitOperation(delegate 
{ 
    // your code 
}); 
+0

और, यदि आप कहना चाहते हैं, हमेशा किसी अन्य धागे में काम करें, तो आपको अपने कोड को अलग करने की आवश्यकता नहीं है (यानी, यह डिज़ाइन मूल्य जोड़ता है) –

+0

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

+0

यह कुछ मामलों में, समेकित सुरक्षा की अनुमति नहीं देता है। उदाहरण के लिए, आप उपज कथन के साथ इस विधि के अंदर इसका उपयोग नहीं कर सकते हैं और गारंटीकृत सफाई प्राप्त कर सकते हैं ... –

6

सिर्फ इसलिए कि आप (या क्योंकि फिल Haack कहते हैं यह ठीक है), इसका मतलब यह नहीं कर सकते हैं करना चाहिए।

अंगूठे का मूल नियम: यदि मैं आपका कोड पढ़ सकता हूं और समझ सकता हूं कि यह क्या कर रहा है और आपका इरादा क्या है, तो यह स्वीकार्य है। अगर, दूसरी तरफ, आपको यह समझाने की ज़रूरत है कि आपने क्या किया है, या आपने ऐसा क्यों किया है, तो शायद यह कोड बनाए रखने वाले जूनियर डेवलपर्स की यात्रा करने जा रहा है।

कई अन्य पैटर्न हैं जो बेहतर encapsulation के साथ इसे पूरा कर सकते हैं।

नीचे की रेखा: यह "तकनीक" आपको कुछ भी नहीं खरीदती है और केवल अन्य डेवलपर्स को भ्रमित करने के लिए कार्य करती है।

+0

+1। मैं पूरी तरह से सहमत हूं - हालांकि, आम तौर पर, मुझे लगता है कि फैक्टर प्रकारों के लिए आईडीस्पोजेबल का उपयोग करना कई मामलों में उन्हें संभालने का एक बहुत ही साफ, समझने योग्य माध्यम प्रदान करता है ... लेकिन यह आपके कोड को सही तरीके से लिखने का विषय है, साथ ही साथ यह स्पष्ट है कि क्या आप कर रहे हैं। यानी: बीसीएल में लेनदेनस्कोप मेरे लिए स्वाभाविक है - इंडेंट कोड यहां दूसरे उत्तर में नहीं है। कई चीजों की तरह, मुझे लगता है कि यह सहायक है, लेकिन आसानी से दुर्व्यवहार किया जा सकता है। –

+0

सहमत हुए। क्या काम करता है, काम करता है। दिलचस्प अवधारणाओं को दूर करना आसान है, लेकिन कुछ भी नहीं जो केवल भ्रमित करने में काम करता है, वास्तविक दुनिया प्रोजेक्ट में उपयोग किया जाना चाहिए। – Charles

+0

अगर यह मुझे भ्रमित लग रहा था, तो मैंने नहीं पूछा होता। संभावित भ्रम को नजरअंदाज करते हुए, क्या आपके पास एक विकल्प है जो साफ या आसान होगा? मुझे पसंद है कि कैसे "उपयोग" इनलाइन, इंडेंट और भाषा समर्थित है, और स्पष्ट रूप से, ठोस और स्पष्ट रूप से गुंजाइश को ढंकता है। – snarf

12

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

मैं अल्पसंख्यक में हूं। अधिकांश लोग ऐसा लगता है कि एक सामान्य उद्देश्य के रूप में "उपयोग" का उपयोग करते हैं "मैं कुछ सफाई कोड चाहता हूं भले ही अपवाद फेंक दिया जाए" तंत्र।

मुझे इससे नापसंद है क्योंकि (1) हमारे पास पहले से ही "कोशिश-अंत" नामक एक तंत्र है, (2) यह उस उद्देश्य के लिए एक सुविधा का उपयोग करता है जिसका उद्देश्य नहीं था, और (3) अगर कॉल क्लीनअप कोड महत्वपूर्ण है, तो यह उस बिंदु पर क्यों दिखाई नहीं दे रहा है जहां इसे कहा जाता है? यदि यह महत्वपूर्ण है तो मैं इसे देखने में सक्षम होना चाहता हूं।

+0

ऐसा लगता है कि यह 'उपयोग' पर लेता है अनजाने में प्रतिबंधक है। जिज्ञासा से बाहर, क्या सी # में कोई अन्य भाषा सुविधा है जहां आप इसके उपयोग के खिलाफ अनुशंसा करेंगे - भले ही यह पूरी तरह से और स्पष्ट रूप से कार्य करे - क्योंकि कहा गया था कि इसका उपयोग किस प्रकार किया गया था? –

+0

@ किर्कवॉल: हाँ। मैं उन * सभी * भाषा सुविधाओं के उपयोग के खिलाफ अनुशंसा करता हूं जो उनके लिए डिज़ाइन किए गए किसी अन्य चीज़ के लिए उपयोग किए जाते हैं। –

+0

@EricLippert - बेशक, यह हमेशा स्पष्ट नहीं होता है कि किस भाषा सुविधा के लिए डिज़ाइन किया गया था। वास्तव में, यहां तक ​​कि 'उपयोग' के विशिष्ट मामले में, मैंने सोचा था कि कुछ संकेत थे कि "उपयोग" नाम विशेष रूप से चुना गया था क्योंकि यह अनुमान लगाया गया था कि सुविधा केवल अप्रबंधित संसाधनों का निपटान करने के लिए उपयोग नहीं की जाएगी। – kvb

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