8

हम इस कोड sortof है,: VS10 अंतिम में13 घटना हैंडलर सदस्यता के साथ एक विधि में चक्रवात जटिलता 27 कैसे हो सकती है?

private void InitializeEvents() 
{ 
    this.Event1 += (s,e) => { }; 
    this.Event2 += (s,e) => { }; 
    this.Event3 += (s,e) => { }; 
    this.Event4 += (s,e) => { }; 
    this.Event5 += (s,e) => { }; 
    this.Event6 += (s,e) => { }; 
    this.Event7 += (s,e) => { }; 
    this.Event8 += (s,e) => { }; 
    this.Event9 += (s,e) => { }; 
    this.Event10 += (s,e) => { }; 
    this.Event11 += (s,e) => { }; 
    this.Event12 += (s,e) => { }; 
    this.Event13 += (s,e) => { }; 
} 

कोड विश्लेषण कहते हैं, "27 के cyclomatic जटिलता"। लाइनों में से एक को हटाने से चक्रवात जटिलता 25.

कोई शाखा नहीं चल रही है, तो यह कैसे संभव है?

उत्तर

17

Remeber कि कोड विश्लेषण आपकी असेंबली में आईएल को देख रहा है, न कि आपके स्रोत कोड। आईएल में कुछ भी नहीं है जो मूल रूप से लैम्ब्डा अभिव्यक्तियों का समर्थन करता है, इसलिए वे कंपाइलर का निर्माण कर रहे हैं। आप आउटपुट here के विनिर्देशों को पा सकते हैं। लेकिन मूल रूप से आपकी लैम्ब्डा अभिव्यक्ति एक निजी स्थैतिक वर्ग में बदल जाती है जो एक अनाम गुमराह है। हालांकि, कोड में संदर्भित हर बार अज्ञात डिलीगेट का एक उदाहरण बनाते हैं, इसलिए डिलीगेट कैश किया जाता है। इसलिए प्रत्येक बार जब आप लैम्ब्डा अभिव्यक्ति आवंटित करते हैं, तो यह उस लम्बा डिलीगेट का एक उदाहरण देखने के लिए एक चेक करता है, यदि ऐसा है तो यह कैश किए गए डिलीगेट का उपयोग करता है। इससे आईएल में 2/2 जटिलता बढ़ने में उत्पन्न होता है। इसलिए इस कार्य में जटिलता 1 + 2 * (लैम्ब्डा एक्सप्रेस) = 1 + 2 * (13) = 27 है जो सही संख्या है।

+0

+1 "रेमेबर कि कोड विश्लेषण आपकी असेंबली में आईएल को देख रहा है, न कि आपके स्रोत कोड में। आईएल में कुछ भी नहीं है जो मूल रूप से लैम्ब्डा अभिव्यक्तियों का समर्थन करता है" – Lijo

+0

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

1

सर्वश्रेष्ठ अनुमान http://msdn.microsoft.com/en-us/magazine/cc163533.aspx और http://www.switchonthecode.com/tutorials/csharp-tutorial-event-accessors घटना एक्सेसर प्रारूप पर विचार विमर्श के लिए देखें, कि यह शायद घटना एक्सेसर प्रारूप करने के लिए परिवर्तित किया जा रहा ऊपर बयान की वजह से है

class MyClass 
{ 
    private event EventHandler MyPrivateEvent; 

    public event EventHandler MyEvent 
    { 
    add 
    { 
     MyPrivateEvent += value; 
    } 
    remove 
    { 
     MyPrivateEvent -= value; 
    } 
    } 
} 

अर्थात्।

3

सी # कंपाइलर वास्तव में लैम्बडा सहित अज्ञात तरीकों के लिए कुछ काफी "दिलचस्प" आईएल उत्पन्न करता है। प्रत्येक के लिए, यह उपभोग विधि में अपना मूल्य निर्दिष्ट करने से पहले, एक निजी क्षेत्र बनाता है, यह जांचता है कि मान शून्य है, जो संकलित विधि में शाखा को जोड़ता है। कोड मीट्रिक उपकरण को इस पर नजरअंदाज करना चाहिए (http://social.msdn.microsoft.com/Forums/eu/vstscode/thread/8c17f569-5ee3-4d26-bf09-4ad4f9289705, https://connect.microsoft.com/VisualStudio/feedback/details/555560/method-using-many-lambda-expressions-causes-high-cyclomatic-complexity), और हम उम्मीद कर सकते हैं कि अंत में । अभी के लिए, अगर आपको लगता है कि यह एक झूठी सकारात्मक है तो आपको समस्या को अनदेखा करना होगा।

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