2009-01-13 5 views
7

मैं अक्सर खुद को ऐसी संपत्ति लिखता हूं जिसका मूल्यांकन आलसी ढंग से किया जाता है। कुछ की तरह:"LazyProperty" वर्ग को कार्यान्वित करना - क्या यह एक अच्छा विचार है?

if (backingField == null) 
    backingField = SomeOperation(); 
return backingField; 

यह बहुत कोड नहीं है, लेकिन यह एक बहुत दोहराया पड़ता कि आप संपत्तियों की एक बहुत कुछ है।

मैं एक वर्ग LazyProperty बुलाया परिभाषित करने के बारे में सोच रहा हूँ: इस तरह एक क्षेत्र प्रारंभ करने में

public class LazyProperty<T> 
    { 
    private readonly Func<T> getter; 

    public LazyProperty(Func<T> getter) 
    { 
     this.getter = getter; 
    } 

    private bool loaded = false; 
    private T propertyValue; 

    public T Value 
    { 
     get 
     { 
      if (!loaded) 
      { 
       propertyValue = getter(); 
       loaded = true; 
      } 
      return propertyValue; 
     } 
    } 

    public static implicit operator T(LazyProperty<T> rhs) 
    { 
     return rhs.Value; 
    } 
} 

यह मैं सक्षम होगा:

first = new LazyProperty<HeavyObject>(() => new HeavyObject { MyProperty = Value }); 

और फिर संपत्ति के शरीर के लिए कम किया जा सकता :

public HeavyObject First { get { return first; } } 

इसका उपयोग अधिकांश कंपनी द्वारा किया जाएगा, क्योंकि यह एक में जाएगा हमारे अधिकांश उत्पादों द्वारा साझा की जाने वाली सामान्य श्रेणी पुस्तकालय।

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

  • कम कोड
  • सुंदर कोड

नकारात्मक पक्ष पर, यह कोड को देखो और निर्धारित वास्तव में क्या होता है करने के लिए कठिन हो सकता है - खासकर अगर एक डेवलपर LazyProperty कक्षा से परिचित नहीं है।

आपको क्या लगता है? क्या यह एक अच्छा विचार है या मुझे इसे छोड़ देना चाहिए? इसके अलावा, निहित ऑपरेटर एक अच्छा विचार है, या आप इस वर्ग का उपयोग करने के लिए स्पष्ट रूप से मूल्य संपत्ति का उपयोग करना पसंद करेंगे?

राय और सुझावों :-)

उत्तर

7

बस बहुत ज्यादा पंडिताऊ होने के लिए:

कोड दोहरा से बचने के लिए अपने प्रस्तावित समाधान:

private HeavyObject first; 
public HeavyObject First { 
    get { 
    if (first == null) first = new HeavyObject { MyProperty = Value }; 
    return first; 
    } 
} 
:

private LazyProperty<HeavyObject> first = 
    new LazyProperty<HeavyObject>(() => new HeavyObject { MyProperty = Value }); 
public HeavyObject First { 
    get { 
    return first; 
    } 
} 

वास्तव में कोड वर्णों से अधिक नहीं है कि आप को दोहराने के लिए नहीं करना चाहता था है

इसके अलावा, मुझे लगता है कि निहित कलाकार ने कोड को समझने में बहुत मुश्किल बना दी है।मैंने अनुमान लगाया नहीं होगा कि एक विधि जो पहले लौटती है, वास्तव में एक हेवी ऑब्जेक्ट बनाने का अंत करती है। मैं कम से कम अंतर्निहित रूपांतरण छोड़ दिया होगा और पहले वापस आ गया होगा। संपत्ति से मूल्य।

+0

आपका बिंदु निहित ऑपरेटर के बारे में नोट किया गया है। यह उन चीजों में से एक है जिनके बारे में मुझे राय चाहिए। – driis

+1

पेडेंटिक होना अच्छा है। +1। – dalle

1

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

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

2

मैं पहला कोड पसंद करता हूं, क्योंकि ए) यह गुणों के साथ एक आम पैटर्न है जिसे मैं तुरंत समझता हूं, और बी) आपके द्वारा उठाए गए बिंदु: कि कोई छुपा जादू नहीं है जिसे आपको देखना है यह समझने के लिए कि मूल्य कहां और कब प्राप्त किया जा रहा है।

1

मुझे नहीं लगता कि एक डेवलपर के बारे में चिंता करने की चिंता नहीं है, ऐसा कुछ करने के खिलाफ एक अच्छा तर्क है ...

आपको लगता है कि उसके बाद आप किसी को समझ नहीं तुम क्या किया के डर से कुछ भी नहीं कर सकता है

आप एक ट्यूटोरियल या एक केंद्रीय भंडार में कुछ लिख सकता है, हम यहाँ इस तरह के लिए एक विकी है नोट

कुल मिलाकर, मैं

0

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

यदि आप कोई धारावाहिक करते हैं तो आपका दृष्टिकोण भविष्य में चिंता का विषय बन सकता है। शुरुआत में यह समझने के लिए कि आप कस्टम प्रकार के साथ क्या कर रहे हैं, यह और अधिक भ्रमित है।

कुल मिलाकर मैं आपके प्रयास की सराहना करता हूं और इसकी चतुरता की सराहना करता हूं लेकिन सुझाव देता हूं कि आप ऊपर बताए गए कारणों के लिए अपने मूल समाधान पर वापस आएं।

4

निश्चित रूप से आप कम से कम LazyPropery<T> मूल्य मान के लिए चाहते हैं, अन्यथा आपने अपने सिस्टम में प्रत्येक "आलसी लोड" संपत्ति के लिए मेमोरी और जीसी दबाव जोड़ा है।

इसके अलावा, एकाधिक थ्रेडेड परिदृश्यों के बारे में क्या? एक ही समय में संपत्ति का अनुरोध करने वाले दो धागे पर विचार करें। लॉकिंग के बिना, आप संभावित रूप से अंतर्निहित संपत्ति के दो उदाहरण बना सकते हैं। सामान्य मामले में लॉकिंग से बचने के लिए, आप एक डबल-चेक लॉक करना चाहते हैं।

+0

लॉक करने के लिए +1 भी अपने डिजाइन हालांकि –

+0

हाँ, मैं propably एक inhertied वर्ग एक ही पैटर्न लागू करने के लिए बनाई गई हैं में काम करने के लिए मुश्किल नहीं है, लेकिन मूल्य गेटर में धागा सुरक्षा के साथ। फिर कक्षा उपभोक्ता यह चुन सकता है कि वह थ्रेड सुरक्षा चाहता है या नहीं। – driis

1

इस मामले में मैं क्या करता हूं, मैं Visual Studio code snippet बना रहा हूं। मुझे लगता है कि आपको वास्तव में क्या करना चाहिए।

उदाहरण के लिए, जब मैं ASP.NET नियंत्रण बनाने के लिए, मैं अक्सर बार है कि ViewState एक बहुत में जमा हो जाता है डेटा है, तो मैं इस तरह के कोड का टुकड़ा बनाया:

public Type Value 
{ 
    get 
    { 
     if(ViewState["key"] == null) 
      ViewState["key"] = someDefaultValue; 
     return (Type)ViewState["key"]; 
    } 
    set{ ViewState["key"] = value; } 
} 

इस तरह, कोड आसानी से केवल एक छोटे से काम के साथ बनाया जा सकता है (प्रकार, कुंजी, नाम, और डिफ़ॉल्ट मान परिभाषित)। यह पुन: प्रयोज्य है, लेकिन आपके पास कोड के जटिल टुकड़े का नुकसान नहीं है जो अन्य डेवलपर्स समझ में नहीं आ सकते हैं।

0

व्यक्तिगत रूप से, मुझे नहीं लगता कि LazyProperty क्लास के रूप में इसका उपयोग करने के लिए पर्याप्त मूल्य प्रदान करता है, विशेष रूप से मूल्य प्रकारों के लिए इसका उपयोग करने वाले दोषों पर विचार करना (जैसा कि केंट का उल्लेख है)। यदि आपको अन्य कार्यक्षमता की आवश्यकता है (जैसे इसे बहुसंख्यक बनाना), तो इसे थ्रेडसेफलाज़ीप्रोपर्टी क्लास के रूप में उचित ठहराया जा सकता है।

निहित संपत्ति के संबंध में, मुझे "मूल्य" संपत्ति बेहतर पसंद है। यह थोड़ा और टाइपिंग है, लेकिन मेरे लिए बहुत अधिक स्पष्ट है।

5

इसे बिल्कुल मत करो।

आम तौर पर आलसी प्रारंभ गुण इस तरह का उपयोग करते हुए एक मामले में एक वैध डिजाइन पसंद है: जब SomeOperation(); एक महंगी ऑपरेशन है (आई/ओ, के मामले में जब यह एक डीबी हिट की आवश्यकता है, या computationally) और जब आप निश्चित हैं कि आपको अक्सर इसे एक्सेस करने की आवश्यकता नहीं होगी।

यह कहा जाता है कि डिफ़ॉल्ट रूप से आपको उत्सुक प्रारंभिकता के लिए जाना चाहिए, और जब प्रोफाइलर कहता है कि यह आपकी बाधा है, तो इसे आलसी प्रारंभ में बदलें।

यदि आप उस तरह के अमूर्तता को बनाने का आग्रह करते हैं, तो यह एक गंध है।

+0

वह यह नहीं पूछ रहा है कि आलसी मूल्यांकन वाले फ़ील्ड वैध विकल्प हैं (जब वह नहीं होता है और जब यह नहीं होता है तो वह भेद को समझता है)। वह पूछ रहा है कि वह जो प्रस्ताव प्रस्तुत करता है वह एक अच्छी डिजाइन पसंद है। –

+0

वैसे वह कहता है कि वह बहुत आलसी चीजें कर रहा है, जो मेरे लिए भी अजीब लगता है। अधिकांश गुणों को आलसी inits इमो की आवश्यकता नहीं है। –

+1

@petr, हाँ, मुझे पता है कि सवाल क्या था। मैं केवल इतना कहता हूं कि यह पूरी तरह से बुरा विचार है, और क्यों। अपने आप को कटौती न करने की चेतावनी, प्रश्न के लिए एक वैध जवाब है "मैं अपने आप को सबसे अच्छा कैसे कर सकता हूं?" –

0

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

मुझे पसंद है कि उदाहरण के लिए लॉकिंग के विवरण को संभालने और संक्षेप में आप इस दृष्टिकोण का उपयोग कैसे कर सकते हैं। यदि आप ऐसा करते हैं तो मुझे लगता है कि मूल्य और योग्यता है। यदि आप डबल लॉक पैटर्न के लिए लॉकिंग घड़ी जोड़ते हैं तो इसे गलत करना बहुत आसान है।

0

आप सी # इटरेटर का उपयोग कर सकते हैं। निम्नलिखित पोस्ट नमूना उपयोग और इसका उपयोग करने के फायदे बताती है।

http://hemanshubhojak.com/Home/Post?postId=3

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

  • कोई संबंधित समस्या नहीं^_^