2009-05-19 10 views
8

और यदि हां, तो क्यों? और "लंबे समय तक चलने" का क्या गठन होता है?क्या यह सच है कि मुझे संपत्ति एक्सेसर में "लंबी दौड़" नहीं करना चाहिए?

एक संपत्ति एक्सेसर में जादू करना कक्षा के डिजाइनर के रूप में मेरे विशेषाधिकार की तरह लगता है। मैंने हमेशा सोचा था कि यही कारण है कि सी # के डिजाइनरों ने उन चीज़ों को वहां रखा - इसलिए मैं जो चाहता हूं वह कर सकता था।

बेशक यह कक्षा के उपयोगकर्ताओं के लिए आश्चर्य कम करने के लिए अच्छा अभ्यास है, और इसलिए वास्तव में लंबे समय तक चलने वाली चीजों को एम्बेड करना - उदाहरण के लिए, एक विधि में 10 मिनट का मोंटे कार्लो विश्लेषण - समझ में आता है।

लेकिन मान लीजिए कि एक प्रोप एक्सेसर को डीबी पढ़ने की आवश्यकता होती है। मेरे पास पहले से ही डीबी कनेक्शन खुला है। डीबी एक्सेस कोड सामान्य स्वीकार्यताओं के भीतर, एक संपत्ति एक्सेसर में "स्वीकार्य" होगा?

+5

फ्रेमवर्क डिजाइन दिशानिर्देश, 1 संस्करण, पृष्ठ 118 के अनुसार, "लंबे समय से चल रहा है" का अर्थ है "परिमाण एक क्षेत्र का उपयोग की तुलना में धीमी के आदेश", और "कहते हैं विशेष रूप से, कि नेटवर्क या फ़ाइल सिस्टम होना चाहिए का उपयोग आपरेशन संभवतः विधियां नहीं, गुण नहीं "। –

+0

यह जानना बहुत अच्छा है। – Cheeso

उत्तर

22

की तरह आप का उल्लेख करने पर विचार ..., यह वर्ग के उपयोगकर्ता के लिए एक आश्चर्य है। लोग गुणों के साथ काल्पनिक उदाहरण इस तरह काम करने के लिए (सक्षम किया जा रहा करने के लिए इस्तेमाल कर रहे हैं इस प्रकार है :)

foreach (var item in bunchOfItems) 
    foreach (var slot in someCollection) 
     slot.Value = item.Value; 

यह बहुत ही स्वाभाविक है, लेकिन यदि item.Value वास्तव में डेटाबेस आप इसे उपयोग हर बार मार रहा है, यह एक छोटी सी होगा आपदा, और एक फैशन बराबर में यह करने के लिए लिखा जाना चाहिए:

foreach (var item in bunchOfItems) 
{ 
    var temp = item.Value; 
    foreach (var slot in someCollection) 
     slot.Value = temp; 
} 

कृपया मदद इस तरह छुपा खतरों से दूर अपने कोड का उपयोग लोगों चलाने, और तरीकों में धीमी गति से बातें रख सकते हैं ताकि लोगों को पता है कि वे धीमी गति से कर रहे हैं।

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

+3

उत्कृष्ट उदाहरण +1 – samjudson

+0

+1, बहुत स्पष्ट और स्पष्ट उदाहरण। साथ ही, इस तथ्य पर प्रकाश डाला गया है कि संपत्ति में डेटा पहुंच डालने से बैच अपडेट निष्पादित करने की क्षमता को रोक दिया जाता है, और क्लास में इस जटिल कार्यक्षमता को बगैर लेनदेन में अपडेट लपेटता है। –

+0

मेरा सामान्य पैटर्न एक बार मूल्य को तत्काल और पुनर्प्राप्त (यदि एनईसी) को पुनर्प्राप्त करना है, तो इसे एक निजी क्षेत्र के रूप में कैश करें। पहली बार एक डीबी एक्सेस, पहली बार पुनर्प्राप्ति के बाद कोई डीबी एक्सेस नहीं, जब तक कि कुछ और नहीं बदला जाता है। – Cheeso

3

एक संपत्ति एक्सेसर में एक डीबी पढ़ा जाएगा ठीक है - वास्तव में आलसी लोडिंग का पूरा बिंदु है। मुझे लगता है कि सबसे महत्वपूर्ण बात यह है कि इसे अच्छी तरह से दस्तावेज किया जाए ताकि कक्षा के उपयोगकर्ता समझ सकें कि उस संपत्ति तक पहुंचने पर प्रदर्शन प्रदर्शन हो सकता है।

1

मुझे नहीं पता कि समस्या क्या है, जब तक आप XML दस्तावेज़ प्रदान करते हैं ताकि इंटेलिसेंस ऑब्जेक्ट के उपभोक्ता को जो कुछ भी प्राप्त कर रहा है उसे सूचित करता हो।

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

3

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

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

+1

+1: मुझे हाल ही में एक संपत्ति एक्सेसर में एक बग द्वारा काटा गया था जो लगभग चला गया और लगभग 1,000,001 चीजें थीं। यह एक ऐसी कनेक्टेड प्रॉपर्टी की तरह है जो वास्तव में एक TryConnect फ़ंक्शन होना चाहिए (अधिक या कम, डोमेन विशिष्ट सामग्री को एक टिप्पणी हाइकू में स्थानांतरित करना मुश्किल है) –

+4

@ बाइनरी वर्रियर: अप्रत्याशित चीजें/कारण दर्द असंख्य/कोड लेने पर। –

3

यह केवल "अच्छा अभ्यास" है कि संपत्ति एक्सेसर्स को निष्पादित करने में लंबा समय नहीं लगेगा। ऐसा इसलिए है क्योंकि गुण कॉलर के लिए फ़ील्ड की तरह दिखते हैं और इसलिए कॉलर (आपके एपीआई का उपयोगकर्ता) आमतौर पर मानता है कि "वापसी की कमी" से कहीं ज्यादा कुछ नहीं है;

तुम सच में पर्दे के पीछे कुछ "कार्रवाई" की जरूरत है, उस के लिए एक विधि बनाने

1

किसी संपत्ति गेटटर में डेटाबेस एक्सेस ठीक है, लेकिन मान को कैशिंग के माध्यम से डेटाबेस को कितनी बार मारा जाता है, इसे सीमित करने का प्रयास करें।

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

डेटा के इस टुकड़े के लिए व्यवहार्य है, तो एक निजी चर में डेटाबेस से लौटाया गया मान कैश करें। इस तरह से एक्सेस आमतौर पर बहुत तेज़ होते हैं।

12

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

इसके अलावा, इस प्रश्न पर व्यापक रूप से फ्रेमवर्क डिजाइन दिशानिर्देशों में चर्चा की गई है; एक प्रतिलिपि लेने पर विचार करें।

+4

सभी को यह पुस्तक मिलनी चाहिए! –

+3

मैंने यह भी सीखा है कि संपत्ति के गेटटर में दुष्प्रभावों के साथ संचालन से बचना बेहतर है। डीबगर में ऑब्जेक्ट्स देखने से उत्पन्न होने वाली आपकी पूंछ को "हेइज़नबग्स" चलाने से भी बदतर कुछ भी नहीं है, जो आपके ऑब्जेक्ट की स्थिति को बदल देता है। (http://en.wikipedia.org/wiki/Unusual_software_bug देखें) – LBushkin

0

यह सीधे आपके प्रश्न से संबंधित नहीं है, लेकिन क्या आपने एक बार ताज़ा पैरामीटर के साथ संयोजन में दृष्टिकोण के साथ एक लोड के साथ जाने पर विचार किया है?

class Example 
    { 
     private bool userNameLoaded = false; 
     private string userName = ""; 
     public string UserName(bool refresh) 
     { 
      userNameLoaded = !refresh; 
      return UserName(); 
     } 
     public string UserName() 
     { 
      if (!userNameLoaded) 
      { 
       /* 
       userName=SomeDBMethod(); 
       */ 
       userNameLoaded = true;      
      } 
      return userName;   
     } 
    }