2009-11-06 12 views
34

तक पहुंच मैं निम्नलिखित कोड है:ReSharper चेतावनी - संशोधित बंद

string acctStatus = account.AccountStatus.ToString(); 
if (!SettableStatuses().Any(status => status == acctStatus)) 
    acctStatus = ACCOUNTSTATUS.Pending.ToString(); 

ध्यान दें कि account.AccountStatus प्रकार ACCOUNTSTATUS का एक enum है। दूसरी पंक्ति पर, रेशेपर मुझे एक्टस्टैटस के लिए "संशोधित बंद करने की पहुंच" चेतावनी दे रहा है।

string acctStatus = realAccount.AccountStatus.ToString(); 
string s = acctStatus; 
if (!SettableStatuses().Any(status => status == s)) 
    acctStatus = ACCOUNTSTATUS.Pending.ToString(); 

क्यों अच्छा है या क्या मैं मूल रूप से किया था बेहतर है: जब मैं सिफारिश संचालन करते हैं, स्थानीय चर को कॉपी, यह निम्न करने के लिए कोड को संशोधित करता है?

string[] acctStatus = {realAccount.AccountStatus.ToString()}; 
if (!SettableStatuses().Any(status => status == acctStatus[0])) 
    acctStatus[0] = ACCOUNTSTATUS.Pending.ToString(); 

यह मेरे लिए पूरी तरह निराला लगता है:

संपादित

यह भी सरणी में लपेटें स्थानीय चर, जो पैदा करता है की सिफारिश की।

+0

इस SO प्रश्न और स्वीकृत उत्तर की जांच करें, सहायक हो सकता है। http://stackoverflow.com/questions/235455/access-to-modified-closure – Chuck

उत्तर

34

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

कल्पना कीजिए कि आपके पास फॉर लूप था और यदि उसके अंदर था और स्ट्रिंग घोषणा इसके बाहर थी। उस स्थिति में त्रुटि अस्थिर कुछ के संदर्भ को पकड़ने की समस्या को सही ढंग से पहचानने वाली होगी।

आप नहीं चाहते क्या का एक उदाहरण:

string acctStatus 

foreach(...) 
{ 
    acctStatus = account.AccountStatus[...].ToString(); 
    if (!SettableStatuses().Any(status => status == acctStatus)) 
     acctStatus = ACCOUNTSTATUS.Pending.ToString(); 
} 

समस्या यह है कि बंद acctStatus के लिए एक संदर्भ हड़पने जाएगा, लेकिन प्रत्येक पाश यात्रा है कि मूल्य बदल जाएगा। (पाश के लिए)

foreach(...) 
{ 
    string acctStatus = account.AccountStatus[...].ToString(); 
    if (!SettableStatuses().Any(status => status == acctStatus)) 
     acctStatus = ACCOUNTSTATUS.Pending.ToString(); 
} 

चर के संदर्भ के रूप में, पाश है एक नया उदाहरण हर बार बनाया जाएगा क्योंकि हम स्थानीय संदर्भ के अंदर चर स्थानांतरित कर दिया: में मामले में यह बेहतर होगा।

सिफारिश उस कोड के Resharper के विश्लेषण में एक बग की तरह लगता है। हालांकि, कई मामलों में यह एक वैध चिंता है (जैसे पहला उदाहरण, जहां बंद होने पर इसके कब्जे के बावजूद संदर्भ बदल रहा है)।

अंगूठे का मेरा नियम है, जब संदेह में स्थानीय बनाते हैं।

 menu.MenuItems.Clear(); 
     HistoryItem[] crumbs = policyTree.Crumbs.GetCrumbs(nodeType); 

     for (int i = crumbs.Length - 1; i > -1; i--) //Run through items backwards. 
     { 
      HistoryItem crumb = crumbs[i]; 
      NodeType type = nodeType; //Local to capture type. 
      MenuItem menuItem = new MenuItem(crumb.MenuText); 
      menuItem.Click += (s, e) => NavigateToRecord(crumb.ItemGuid, type); 
      menu.MenuItems.Add(menuItem); 
     } 

ध्यान दें कि मैं NodeType प्रकार स्थानीय कब्जा, ध्यान दें nodeType, और HistoryItem crumb.ItemGuid, टुकड़ों [i] .ItemGuid नहीं:

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

स्थानीय लोगों का उपयोग करने से पहले, घटनाएं मौजूदा मूल्यों के साथ ट्रिगर होंगी, न कि कैप्चर किए गए मूल्यों की अपेक्षा।

+0

बहुत समझ में आता है, धन्यवाद! –

+1

"समस्या यह है कि बंद करने से एक्टस्टैटस का संदर्भ प्राप्त होगा, लेकिन प्रत्येक लूप पुनरावृत्ति उस मान को बदल देगी" - वास्तव में यह हमेशा 'खाता' होगा। खाता स्थिति [...]। ToString() 'जब भी' कोई भी 'predicate इसका मूल्यांकन करता है (क्योंकि 'कोई भी' लौटने से पहले गणना करने पर पुनरावृत्त होता है), इसलिए मुझे यकीन नहीं है कि यह एक अच्छा उदाहरण है। मेरा मानना ​​है कि आपने जो बेहतर प्रस्ताव दिया है, वही व्यवहार होगा। –

+1

यह गलत होगा। अंतर का कारण यह है कि पहले उदाहरण में केवल एक चर आवंटित किया जाता है: acctStatus। Resharper चिंतित है कि यह चर किसी भी() वास्तव में मूल्यांकन किया गया है इससे पहले बदल जाएगा। मेरा सुझाव कोड की क्रिया को बिल्कुल भी नहीं बदलता है (किसी भी बदलाव से पहले किसी भी() का मूल्यांकन किया जाता है) लेकिन यह स्पष्ट करता है कि हम लूप के प्रत्येक पुनरावृत्ति के लिए परिवर्तनीय एक्टस्टैटस का एक विशिष्ट उदाहरण चाहते हैं। यदि आप मेरे बाद के उदाहरण को नोट करते हैं, तो बग रिशेर्पर वास्तव में ट्रिगर्स के बारे में चिंतित है क्योंकि मैं तुरंत * लैम्ब्डा (स्थानीय लोगों से कम) का मूल्यांकन नहीं करता हूं। – Godeke