2010-06-10 9 views
6

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

string id; 
string actual; 
string stored; 

if (!someDictionary.TryGetValue (id, out stored) || stored != actual) { 
    // id not known yet or associated value changed. 
} 

उत्तर

1

यह मेरे लिए ठीक लग रहा है ... किसी अन्य 2 हालत अगर बयान के रूप में के रूप में आसान पढ़ता है। के बारे में केवल एक चीज मैं संभवतः बदल देंगे एक प्रारंभिक बाहर निकलने के लिए negations फ्लिप करने के लिए है:,

if (someDictionary.TryGetValue(id, out stored) && stored == actual) { 
    return; 
} 
// store new value 

मैं बिल्कुल नहीं उस में किसी भी भ्रम दिख रहा है, एक विशेष रूप से परेशानी मुहावरा के रूप में कभी नहीं सोचा है और नम्रता से सुझाव देते हैं कि उन सी # देवताओं ने इसे भ्रमित कर दिया है। यह सामान्य है, succint, और समस्या के लिए कई एलओसी देता है क्योंकि यह हकदार है। इसे कोड की 10 लाइनों में बदलना इसे रास्ता बहुत महत्वपूर्ण बनाता है।

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

+2

यह किसी भी 2-शर्त कथन के समान नहीं है क्योंकि इसे 'आउट' पैरामीटर की पूर्व-घोषणा की आवश्यकता है। "…इस्की आद्त डाल लो?" ऐसा नहीं है कि देव "भ्रमित" हैं, * प्रति * *। यहां तक ​​कि एक अनुभवी प्रोग्रामर जो बाएं से दाएं को पढ़ता है, उसे पढ़ने के लिए आगे बढ़ना है, और इसे पढ़ने के लिए दिमाग में कई तत्वों को जोड़ना है। यह एक * कठिन * कार्य नहीं है, लेकिन यह प्राकृतिक नहीं है, या तो। यह कुछ हद तक प्रक्रियात्मक कोड है और पुनरावृत्ति और त्रुटि के अवसर प्रदान करता है। पठनीयता एक वैध चिंता है और 'बूल' परिणाम के साथ 'TryGetValue' अर्थात् कमजोर है। – Jay

+0

@Jay: आप आउट वैरिएबल की घोषणा क्यों जांचेंगे? यह स्पष्ट रूप से वहां है (या संकलक शिकायत करेगा), और आपको इस बात परवाह नहीं करना चाहिए कि मूल्य पहले क्या था (चूंकि यह एक बाहरी है, इसलिए फ़ंक्शन द्वारा मूल्य का उपयोग नहीं किया जाता है)। क्या यह वास्तव में सशर्त के बजाय 'बाहर' के बारे में है? केवल एक ही बिंदु के बारे में मैं इस कथन पर स्वीकार करता हूं कि 1.) दुष्प्रभाव सशर्त में हैं, और 2.) सशर्त आदेश-निर्भर हैं। 'बूल आज़माएं * (बाहर)' बीसीएल में एक अच्छी तरह से स्थापित मुहावरे है कि मैं देवताओं को ग्रोक करने की उम्मीद करता हूं, इसलिए मैं पहले माफ कर देता हूं। –

+0

@Jay: आपकी टिप्पणी "स्पॉट-ऑन" है। मेरी राय में, उत्तर में से कोई भी जवाब पठनीयता नहीं है। यही कारण है कि मैंने अपने सुझाए गए कोड का योगदान दिया। – AMissico

4

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

bool isKnown = someDictionary.TryGetValue (id, out stored); 
// can only change when it is known 
bool valueChanged = isKnown && stored != actual; 

// quite self-explanatory, isn't it? 
if (!isKnown || valueChanged) 
{ 

} 
+0

यह प्रारंभ किया गया है, ऑपरेटर प्राथमिकता नियमों के संयोजन में 'आउट' कीवर्ड संयोजन सुनिश्चित करता है। – mafu

+0

फ़ंक्शन के अंदर एक आउट पैरामीटर सेट किया जाना चाहिए ताकि TryGetValue इसे प्रारंभ कर सके। –

+1

'संग्रहित' हमेशा 'TryGetValue' पर कॉल के बाद प्रारंभ किया जाता है। यह 'आउट' पैरामीटर का नियम है। जाहिर है, यह वैध मान नहीं है। – leppie

2

द्वंद्व।

if (!(someDictionary.TryGetValue (id, out stored) && stored == actual)) ... 

सुनिश्चित नहीं है कि यह अधिक पठनीय है हालांकि ... लेकिन यह जानना अच्छा है।

+2

मुझे लगता है कि मूल से पढ़ना मुश्किल है। पढ़ने योग्य नहीं के लिए – mafu

+0

-1। मुझे इन बयानों को समझने और ठीक करने में परेशानी होगी। विशेष रूप से, क्योंकि 'संग्रहीत' 'बाहर' है, तो आप इसे उसी कथन में उपयोग करते हैं। क्या हो रहा है यह समझने के लिए आप मुझे प्रत्येक तत्व को पढ़ने के लिए मजबूर कर रहे हैं। – AMissico

+0

@AMissico: प्रक्रियात्मक कोड के नुकसान :) – leppie

3

|| के प्रत्येक भाग को लपेटें || अपनी ही विधि या संपत्ति में, की तुलना में आप इस

if (IdIsNew() || IdChanged()) 
+0

मैं कोड की कई पंक्तियों को लिखने से बचना पसंद करूंगा। – mafu

+2

मैं नई विधियां नहीं बनाऊंगा जबतक कि वे किसी भी संभावित त्रुटियों को खत्म नहीं करेंगे। अगर यह पठनीयता और रखरखाव बढ़ता है तो मैं नई विधियों का निर्माण करूंगा। – AMissico

1

तरह लिख सकते हैं मैं एक नई विधि पसंद करते हैं: मौजूदा विधि में

public bool ShouldSetValue(Dictionary someDictionary, object id,object actualValue) 
{ 
    string stored; 

    if (someDictionary.TryGetValue (id, out stored)) 
    { 
     if (stored != actualValue) 
      return true; 
    } 
    else 
    { 
     return true; 
    } 
} 

तो मैं बस चाहता हूँ:

if (ShouldSetValue(someDictionary,id,actual)) 
{ 
    someDictionary[id]=actual; 
} 
+2

'AddValue' विधि के लिए एक भयानक नाम है जो वास्तव में कुछ भी नहीं करता/mutate नहीं करता है। 'CanAddValue' एक बेहतर नाम हो सकता है। – leppie

+0

अच्छा विचार। शायद शब्दकोश के लिए एक विस्तार विधि? और नामकरण अभी तक अजीब है। – mafu

+0

सहमत नामकरण अजीब था। उसे बदल दिया।और हाँ, आप इसे शब्दकोश पर एक विस्तार विधि के रूप में कार्यान्वित कर सकते हैं, जो शायद इसे थोड़ा अच्छा बना देगा ... –

5

आप एक अच्छा नाम के साथ एक विस्तार विधि लिख सकते हैं:

public static class Utility 
{ 
    public static bool ValueChangedOrUnknown(this Dictionary<string, string> dictionary, string id, string actual) 
    { 
     string stored = null; 
     return (!dictionary.TryGetValue(id, out actual) || stored != actual); 
    } 
} 

तो बाद में आप

string id; 
string actual; 

if (someDictionary.ValueChangedOrUnknown(id, actual) { 
    // id not known yet or associated value changed. 
} 
+1

+1। मुझे "आउट" पैरामीटर से नफरत है, और मैं आम तौर पर एक प्रयास विधि के साथ TryGetValue तक किसी भी पहुंच को लपेटता हूं (उदाहरण के लिए सीधे प्रविष्टि को वापस करने के लिए TryGetValueOrDefault, या शून्य या 0 अगर यह प्रविष्टि नहीं मिल पाता है)। –

+0

"आउट" = अस्पष्ट कोड – AMissico

0

एक विस्तार विधि का उपयोग चालाक हो जाएगा कर सकते हैं:

public static class DictionaryExtensions 
{ 
    public static bool ShouldAddValue<TKey, TValue>(this Dictionary<TKey, TValue> someDictionary, TKey id, TValue actual) 
    { 
     TValue stored; 
     return (!someDictionary.TryGetValue(id, out stored) || !stored.Equals(actual)); 
    } 
} 

उपयोग:

someDictionary.ShouldAddValue("foo", "bar") 
0

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

public static class DictionaryExtensions 
{ 
    public static DictionaryChecker<TKey,TValue> contains<TKey,TValue>(this IDictionary<TKey,TValue> dictionary, TValue value) 
    { 
     return new DictionaryChecker<TKey,TValue>(value, dictionary); 
    } 
} 

public class DictionaryChecker<TKey,TValue> 
{ 
    TValue value; 
    IDictionary<TKey,TValue> dictionary; 

    internal DictionaryChecker(TValue value, IDictionary<TKey, TValue> dictionary) 
    { 
     this.value = value; 
     this.dictionary = dictionary; 
    } 

    public bool For(TKey key) 
    { 
     TValue result; 
     return dictionary.TryGetValue(key, out result) && result.Equals(value); 
    } 
} 

अब के साथ अपने कोड के स्थान पर:

if(!someDictionary.contains(actual).For(id)){ 
    // id not known yet or associated value changed. 
} 
+2

बहुत अधिक कोड। कुछ आसान के लिए बहुत जटिल है। – AMissico

+0

@AMissico "बहुत अधिक कोड" व्यक्तिपरक है। यह डोमेन और उपयोग की जरूरतों पर निर्भर करता है। यह सिर्फ एक दृष्टिकोण के रूप में पेश किया जाता है जो उपयोग में पठनीयता का समर्थन करता है, और केवल तभी समझ में आता है जब यह कई जगहों पर एक चेक था। पैरामीटर बढ़ने की संख्या के रूप में पठनीयता कम हो जाती है; यदि आप ऐसा करने में मूल्य देखते हैं, तो यह अवक्रमण को कम करने का एक तरीका है। – Jay

+0

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

0
public T GetValue(int id, object actual) 
{ 
    object stored; 
if (someDictionary.TryGetValue (id, out stored) || stored == actual) 
    return stored; 
    return new object(); 
} 
0

मैं पहचान है कि "कोशिश" पैटर्न के लिए आवश्यक है, मैं कार्यान्वयन करना, जिससे एक "बाहर" पैरामीटर की आवश्यकता होती है नापसंद करते हैं। यह प्रतीत होता है और अधिक उपयोगी TryGetValue के समान कार्य है:

  • TryGetDictValue (शब्दकोश, कुंजी) अशक्त लौटाता है यदि कुंजी शब्दकोश में नहीं है
  • TryGetDictValue (शब्दकोश, कुंजी, DefaultValue) रिटर्न DefaultValue यदि कुंजी में नहीं है शब्दकोश
  • TryGetDictValue (शब्दकोश, कुंजी, valueReturningDelegate) की आपूर्ति की प्रतिनिधि का आह्वान करता है, तो कुंजी शब्दकोश में नहीं है और इसकी परिणाम देता है

हर मामले में, परिणाम की वापसी प्रकार शब्दकोश के डेटा की है कि होगा।

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

+0

यह अभी भी एक्सटेंशन विधि के रूप में किया जा सकता है, जो शायद आपकी आखिरी टिप्पणी के साथ आपका मतलब है। – Dykam

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