क्या उपयोग () कथन के अंदर से लौटने के कोई दुष्प्रभाव हैं?


125

डेटा का उपयोग करने वाले स्टेटमेंट के अंदर से एक विधि मान लौटाते हुए लगता है कि यह हमेशा ठीक काम करता है , जैसे:

public static Transaction GetMostRecentTransaction(int singleId)
{
    using (var db = new DataClasses1DataContext())
    {
        var transaction = (from t in db.Transactions
                              orderby t.WhenCreated descending
                              where t.Id == singleId
                              select t).SingleOrDefault();
        return transaction;
    }
}

लेकिन मुझे हमेशा ऐसा लगता है कि मुझे कुछ को बंद करना चाहिए इससे पहले कि मैं ब्रैकेट्स का उपयोग कर बाहर निकल जाऊं, जैसे कि स्टेटमेंट का उपयोग करने से पहले लेन-देन को परिभाषित करके, इसे कोष्ठक के अंदर मान लें , और फिर कोष्ठक के बाद वापस आ जाएं ।

का उपयोग कर कोष्ठक के बाहर चर को परिभाषित करना और वापस करना बेहतर होगा और किसी भी तरह से संसाधनों का संरक्षण करना होगा?


1
इस के वेरिएंट के लिए सामान्य आईएल को देखना दिलचस्प हो सकता है। मुझे संदेह है कि उत्पन्न IL में बहुत कम अंतर होगा। मैं आमतौर पर var लेन-देन की घोषणा करने से भी परेशान नहीं होता - बस अभिव्यक्ति का परिणाम लौटाता हूं।
जोंसी

जवाबों:


164

नहीं, मुझे लगता है कि यह इस तरह से स्पष्ट है। चिंता न करें, Disposeअभी भी "बाहर निकलने के रास्ते पर" कहा जाएगा - और वापसी के मूल्य का पूरी तरह से मूल्यांकन करने के बाद ही । अगर किसी भी बिंदु पर एक अपवाद को फेंक दिया जाता है (वापसी मूल्य का मूल्यांकन करने सहित) Disposeअभी भी कहा जाएगा।

जब आप निश्चित रूप से लंबा रास्ता तय कर सकते हैं, तो यह दो अतिरिक्त लाइनें हैं जो सिर्फ (मानसिक रूप से) नज़र रखने के लिए cruft और अतिरिक्त संदर्भ जोड़ते हैं। वास्तव में, आपको वास्तव में अतिरिक्त स्थानीय चर की आवश्यकता नहीं है - हालांकि यह डिबगिंग के मामले में आसान हो सकता है। तुम बस हो सकता है:

public static Transaction GetMostRecentTransaction(int singleId)
{
    using (var db = new DataClasses1DataContext())
    {
        return (from t in db.Transactions
                orderby t.WhenCreated descending
                where t.Id == singleId
                select t).SingleOrDefault();
    }
}

वास्तव में, मुझे डॉट नोटेशन का उपयोग करने के लिए भी लुभाया जा सकता है, और इस Whereशर्त को इस प्रकार रखा जाएगा SingleOrDefault:

public static Transaction GetMostRecentTransaction(int singleId)
{
    using (var db = new DataClasses1DataContext())
    {
        return db.Transactions.OrderByDescending(t => t.WhenCreated)
                              .SingleOrDefault(t => t.Id == singleId);
    }
}

2
साइन इट इट यू @ जोंन, क्या यह अभी भी सुरक्षित है अगर अपवाद ब्लॉक के अंदर फेंक दिया जाता है?
डेव आर्चर

6
हाँ। एक कोशिश / अंत में निर्माण के लिए सिंटैक्टिक शुगर का उपयोग करना है
मिच गेहूं

@ डेविड: जैसा कि मिच कहते हैं, यह ठीक है - मैंने यह स्पष्ट करने के लिए उत्तर अपडेट किया है :)
जॉन स्कीट

2
SingleOrDefault के साथ संयोजन में OrderByDescending का उपयोग क्यों करें?
erkkallen

2
@erikkallen: LINQ में "MaxBy" नहीं है, दुर्भाग्य से - इसलिए आपको अधिकतम मान के साथ पंक्ति नहीं मिल सकती है। LINQ ऑब्जेक्ट्स के लिए आप अपना स्वयं का काफी आसानी से लिख सकते हैं, लेकिन मैं इस मामले में इसे करने के बेहतर तरीके के बारे में सुनिश्चित नहीं हूं। इसके बजाय आप क्या सुझाव देंगे?
जॉन स्कीट

32

कृपया एक नज़र इसे देखिये

C # में 'उपयोग' कथन को समझना

CLR आपके कोड को MSIL में बदल देता है। और उपयोग किए गए कथन को एक कोशिश और अंत में ब्लॉक करने में अनुवाद किया जाता है। इस प्रकार IL में स्टेटमेंट का उपयोग किया गया है। एक उपयोग कथन को तीन भागों में अनुवादित किया गया है: अधिग्रहण, उपयोग और निपटान। संसाधन को पहले अधिग्रहित किया जाता है, फिर उपयोग को अंतिम विवरण के साथ एक कोशिश बयान में संलग्न किया जाता है। वस्तु तब अंत में खंड में समा जाती है।


4
एक दिलचस्प अंतर्दृष्टि। धन्यवाद।
कंगण

1
इस प्रश्न का अनुवाद करता है: किसी प्रयास के अंत में ब्लॉक से लौटने का कोई दुष्प्रभाव?
हेंक होल्टरमैन

3
नहीं, अंत में हमेशा कहा जाएगा। techinterviews.com/interview-questions-for-c-developers
एड्रियन

6

एक बयान के अंदर से लौटने के कोई दुष्प्रभाव नहीं हैं using()

क्या यह सबसे पठनीय कोड बनाता है एक और चर्चा है।


0

मुझे लगता है, यह सब समान है। कोड में कुछ भी बुरा नहीं है। .NET फ्रेमवर्क परवाह नहीं करेगा कि ऑब्जेक्ट कहाँ बनाया गया है। वह चीज जो मायने रखती है कि वह संदर्भित है या नहीं।


-1

हां, इसका साइड इफेक्ट हो सकता है। उदाहरण के लिए, यदि आप ASP.NET MVC एक्शन विधि में एक ही तकनीक का उपयोग करते हैं, तो आपको निम्नलिखित त्रुटि मिलेगी: "ObjectContext उदाहरण को निपटाया गया है और अब उन ऑपरेशनों के लिए उपयोग नहीं किया जा सकता है जिनके लिए कनेक्शन की आवश्यकता होती है"

public ActionResult GetMostRecentTransaction(int singleId)
{
    using (var db = new DataClasses1DataContext())
    {
        var transaction = (from t in db.Transactions
                              orderby t.WhenCreated descending
                              where t.Id == singleId
                              select t).SingleOrDefault();
        return PartialView("_transactionPartial", transaction);
    }
}

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