2010-02-04 19 views
14

क्या यह बराबर है?बनाम लैम्ब्डा का उपयोग

 public static void Using<T>(this T disposable, Action<T> action) 
      where T:IDisposable 
     { 
      try { 
       action(disposable); 
      } 
      finally { 
       disposable.Dispose(); 
      } 
     } 

     new SqlConnection("").Using(conn => { 

     }); 

     using(var conn = new SqlConnection("")){ 

     }; 

दूसरे शब्दों में, क्या हम इस विधि के साथ कीवर्ड का उपयोग कर प्रतिस्थापित कर सकते हैं?

+5

आप इस लेख को भी देखना चाहेंगे: http://marcgravell.blogspot.com/2009/11/selectmany-combining-idisposable-and.html मार्क ग्रेवल द्वारा। –

+3

ईमानदार प्रश्न: आप क्यों चाहेंगे? – Justin

+1

ओकम का रेज़र। – dotneter

उत्तर

19

मुझे नहीं लगता कि यह एक विशेष रूप से अच्छा विचार है, क्योंकि यह भी हमें

var conn = new SqlConnecction(""); 
conn.Using(c => /* do something with c */); 
conn.Open(); 

यह संकलन होगा लिखने के लिए अनुमति होगी, लेकिन जब आप अंतिम पंक्ति तक पहुँचने, यह एक ObjectDisposedException फेंक देते हैं।

किसी भी मामले में, using कोडिंग मुहावरे अच्छी तरह से जाना जाता है, तो अपने साथी डेवलपर्स के लिए अपना कोड पढ़ने में कठिनाई क्यों होती है?

+11

यह "क्लासिक" 'कथन का उपयोग कर भी हो सकता है:' var conn = ...; (कॉन) का उपयोग {...}; conn.Open(); ' – Heinzi

+0

मैं इस प्रतिस्थापन को केवल सिद्धांत में मानता हूं, ओकम के रेज़र सिद्धांत का उपयोग करते हुए। – dotneter

+3

@ हिनजी हम यही कारण है कि हम अपने कोडिंग मानकों में लागू होते हैं कि उपयोग खंड में ऑब्जेक्ट को भी उपयोग खंड में परिभाषित किया गया है - यानी 'उपयोग (आईडीबीकनेक्शन con = ...) {...} ' –

2

एक सीमा: यदि आप अपने लैम्ब्डा में युक्त विधि के मापदंडों बाहर acces नहीं कर सकते। disposable जा रहा है null के लिए

2

using बयान जाँच करता है। रनटाइम पर इसके अलावा आपको अधिकतर वही व्यवहार मिलेगा (अतिरिक्त stack frame के अलावा, और प्रतिनिधि कॉल)।

1

के रूप में रिचर्ड ने कहा, डिस्पोजेबल वस्तु के निर्माण और कोशिश की शुरुआत के बीच एक अतिरिक्त विधि कॉल है। यह उस समय सीमा को बढ़ाता है जिसमें एक एसिंक्रोनस अपवाद हो सकता है, जिससे आपके डिस्पोजेबल ऑब्जेक्ट का निपटारा नहीं किया जाता है। हालांकि, यह एक बड़ा मुद्दा नहीं है, क्योंकि IDISposable को लागू करने वाले प्रकारों को अपने संसाधनों को कन्स्ट्रक्टर में प्राप्त नहीं करना चाहिए (एसक्यूएलकनेक्शन ओपन() विधि को कॉल के दौरान अपने संसाधनों को प्राप्त करता है)।

इसलिए जब कथन का उपयोग लिख काम करेगा, यह बहुत कठिन अन्य डेवलपर्स के लिए पढ़ने बनाता है और आसानी से रास्ता मार्क सीनैन नोटों में दुरुपयोग किया जा सकता है के अपने नए तरीके से।

तो क्या आप अपने उपयोग एक्सटेंशन विधि के साथ उपयोग करने वाले कीवर्ड को प्रतिस्थापित कर सकते हैं? हाँ। क्या आपको यह करना चाहिए? संख्या

2

कुछ कारणों से मैं इसका उपयोग क्यों नहीं करना चाहूंगा।

संकलन समय foolproofing

using (var foo=new Bar()) 
{ 
    foo=new Bar();// throws an error at compile time 
} 

Structs IDisposable को लागू करने के लिए जब एक अंतरफलक विधि उन पर शुरू हो जाती है

Structs को लागू करने इंटरफेस बॉक्सिंग कर रहे हैं। उपयोग कथन यह समझने के लिए पर्याप्त स्मार्ट है कि इसका लक्ष्य संकलन समय पर एक संरचना है और मुक्केबाजी से गुजरता है।

+1

तकनीकी रूप से, structs के बारे में थोड़ा वास्तव में एक कंपाइलर बग है। यह कहता है कि मुक्केबाजी रूपांतरण करना है; कार्यान्वयन ऐसा नहीं करता है; यह सिर्फ निपटान() को सीधे कॉल करता है। यह तर्कसंगत रूप से "अधिक सही" चीज करने के लिए है; यदि डिस्प्लेर संरचना को बदलता है, तो शायद यह मूल रूप से एक बॉक्सिंग प्रति नहीं, मूल को म्यूट करना चाहिए। –

+0

यह एक बग नहीं है, यह भविष्य के सीएलआर संस्करणों की एक विशेषता है;) –

10

मुझे लगता है कि आपकी विधि सब कुछ नहीं करती है जो "उपयोग" कथन करता है। उदाहरण के लिए, यह एक नई स्थानीय परिवर्तनीय घोषणा स्थान पेश नहीं करता है जिसमें संसाधन पर रखे गए एक चर को घोषित किया जा सकता है।

न ही यह एक ही प्रकार के कई डिस्पोजेबल संसाधनों के लिए अनुमति नहीं है एक बार में सभी घोषित किया जाना है।

और अंत में, यह अपने आप के साथ विशेष रूप से सुंदर ढंग से रचना करने के प्रतीत नहीं होता।

using(something) 
using(someotherthing) 
using(somethirdthing) 
{ 
    use all three, they'll all get disposed 
} 

कि अपने प्रस्ताव में कैसे दिखेगा: एक बयान के रूप में "का उपयोग" के बारे में अच्छा बातों में से एक यह है कि आप कह सकते है?

something.Using(
x=>someotherthing.Using(
y=>somethirdthing.Using(
z=> { use all three }))); 

थोड़ा सकल, स्पष्ट रूप से।

0

यह है लगभगकार्यात्मक बराबर है, लेकिन व्यावहारिक रूप से बोल रहा है यह कोई लाभ प्रदान नहीं करता है। "पारंपरिक" using कथन के अर्थशास्त्र अच्छी तरह से ज्ञात और मानक हैं। जबकि आपका दृष्टिकोण वही व्यवहार कर सकता है (हालांकि कुछ मतभेद हैं) यह अनावश्यक ओवरहेड और जटिलता पेश करता है - न केवल आपके पास अतिरिक्त विधि आमंत्रण हैं जो आप कोड को दोहराते हैं कि संकलक स्वचालित रूप से उत्पन्न होगा।

0

सं आप एक सामान्य कीवर्ड कॉल के लिए एक भाषा कीवर्ड का अर्थ दे रहे हैं [जिसका मतलब है कि कंपाइलर फ्लोरियन द्वारा इंगित किए गए कुछ हिस्सों को इसके आसपास कर सकता है]।

हालांकि अर्थात् वे समान हो सकते हैं, संकलक यह नहीं जान पाएगा कि विधि क्या करेगी। संकलन समय चेक रनटाइम अपवादों से बेहतर हैं, जैसा कि हम सभी जानते हैं।

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