2012-03-28 16 views
5

मैं कोड के टुकड़े है जो की एक बहुत कुछ आरंभीकरण के दौरान एक बार चलाने के लिए है के साथ एक फ्यूज कर।एक बूलियन

:

मैं क्योंकि यह एक घटना

bool _fuse; 

void PerformLayout() 
{ 
    Size size; 

    if (!_fuse) 
    { 
     size = _InitialContainerSize; 
     _fuse = true; 
    } 
    else 
     size = parent.Size; 

    // ... 
} 

क्योंकि यह अक्सर होता है में है एक बूलियन ध्वज इस तरह से उपयोग करने के लिए, मैं कुछ एक फ्यूज की तरह लग रहे करने के लिए इस बूलियन चर बनाने के लिए किया था

bool _fuse; 

void PerformLayout() 
{ 
    Size size; 

    if (!Burnt(ref _fuse)) 
     size = _InitialContainerSize; 
    else 
     size = parent.Size; 

    // ... 
} 

यह गलत पर आरंभ नहीं हो जाता है, तो क्वेरी का परिणाम एक बार झूठी देता है, switc बनाने:

तो मैं इस किया था एच सच है, और लगातार कॉल सही लौटते हैं।

public static bool Burnt(ref bool value) 
{ 
    if (!value) 
    { 
     value = true; 
     return false; 
    } 
    else 
     return true; 
} 
बेशक

, यह काम करता है, लेकिन मैं केवल मामूली संतुष्ट हूँ और मुझे यकीन है कि वहाँ है और अधिक सुरुचिपूर्ण समाधान कर रहा हूँ। तुम्हारा क्या होगा?

+2

'वापसी मान || ! (मूल्य = true); '(सिर्फ मजाक कर!) –

+0

दिलचस्प। अभी तक टैली तीन अपवॉट्स और तीन वोट बंद हैं। –

+0

कोई असली सवाल नहीं है। कोडरेव्यू साइट पर होना चाहिए। यहाँ नहीं। – leppie

उत्तर

1

मुझे लगता है कि यहाँ पुनरावृत्ति से बचने में सामान्य जोर सही (भले ही पुनरावृत्ति बहुत छोटा है ... लेकिन अभी भी है: तुम भी तरह (moderatly तेजी से) तरीके के साथ एक सरल राज्य मशीन में दोनों समाधान गठबंधन करने के लिए तय कर सकते हैं)। बस इसे संपुटित और इसे ठीक से नाम:

struct InitializerGuard { 
    private bool hasRun; 

    public bool HasRun() { 
     if (hasRun) 
      return true; 
     hasRun = true; 
     return false; 
    } 
} 

उपयोग:

InitializerGuard sizeInitializer; 

void PerformLayout() 
{ 
    Size size; 

    if (!sizeInitializer.HasRun()) 
     size = _InitialContainerSize; 
    else 
     size = parent.Size; 

    // ... 
} 

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

+1

या बस: 'आकार का आकार = HasRun()? अभिभावक। आकार: _initSize; ' – leppie

+0

यह सुरुचिपूर्ण और साफ है। मुझें यह पसंद है। मुझे लगता है कि मैं इसे कॉपी करने जा रहा हूं। (हो सकता है कि मैं हैसुन विधि को इसके बजाय किसी संपत्ति में बदल दूं?) - मैं संभवतः अपने कोड के कुछ हिस्सों को बेहतर तरीके से दोबारा कर सकता हूं, लेकिन कई मामलों में मुझे पसंद नहीं है क्योंकि इसका उपयोग कुछ घटनाओं में किया जाता है, और कोड राशि के लिए कुछ init की आवश्यकता होती है पहली आग – Larry

+1

@Laurent गुणों के दुष्प्रभाव नहीं होने चाहिए। कम से कम, यह आपके डीबगर को खराब करता है (यदि आप अपना कोड डीबग करते हैं और इस चर के लिए घड़ी जोड़ते हैं, तो संपत्ति का मनमाना समय पर मूल्यांकन किया जाता है, इस प्रकार आपका व्यवहार बदलता है)। तो यदि आप इसे एक संपत्ति बनाते हैं, तो आप अपना कोड "दिलचस्प" तरीकों से तोड़ देते हैं। ;-) –

1

आप एक Size संपत्ति घोषित करने के लिए नल प्रकार और अशक्त कोलेसिंग ऑपरेटर का उपयोग कर सकते हैं:

Size? _containerSize; 

Size ContainerSize { 
    get { 
    return (_containerSize ?? (_containerSize = _InitialContainerSize)).Value; 
    } 
} 

फिर आप इस तरह उपयोग कर सकते हैं:

void PerformLayout() { 
    var size = ContainerSize; 
    // ... 
} 

प्रकार आप आलसी प्रारंभ करने में चाहते हैं एक संदर्भ प्रकार है यह भी आसान हो जाता है।

एक अन्य विकल्प Lazy<T> प्रकार का उपयोग करने के लिए है। इस बहु-सूत्रण स्थितियों में इस्तेमाल किया जा सकता है, जहां ऊपर कोड तोड़ सकते हैं:

Lazy<Size> _containerSize = new Lazy<Size>(() => _InitialContainerSize); 

void PerformLayout() { 
    var size = _containerSize.Value; 
    // ... 
} 
1

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

public class TestClass 
{ 
    private Action performLayoutAction; 

    public TestClass() 
    { 
     // initial state 
     performLayoutAction = InitializePeformLayout; 
    } 

    public void PerformLayout() 
    { 
     performLayoutAction(); 
    } 

    private void InitializePeformLayout() 
    { 
     // whatever 

     performLayoutAction = ContiniousPerformLayout; 
    } 

    private void ContiniousPerformLayout() 
    { 
     // whatever 
    } 
} 
संबंधित मुद्दे