2014-10-29 7 views
14

मैं हमारी परियोजनाओं में स्थिर कोड विश्लेषण का उपयोग संहिता के उल्लंघन के लिए जाँच करने के लिए। बड़े पैमाने पर इस्तेमाल किए गए नियमों में से एक सीए 2213 है, जो डिस्पोजेबल फ़ील्ड के सही निपटान के लिए जांच करता है।CA2213 कोड विश्लेषण नियम और ऑटो कार्यान्वित गुण

मैं CA2213 ऑटो कार्यान्वित गुण के निपटान की जाँच नहीं करता देखा।

इसके अलावा CA2213 न खेतों और न ही ऑटो कार्यान्वित गुण के निपटान अगर वर्ग वर्ग जो IDisposable लागू करता है और निपटान विधि पर हावी नहीं होता से विरासत जांच नहीं करता।

व्यावहारिक उदाहरण:

public sealed class Good : IDisposable { 
    private Font font; 
    public Font Font { 
     get { return font; } 
     set { font = value; } 
    } 
    public Good() { font = new Font("Arial", 9); } 
    public void Dispose() { /* Do nothing */ }  // CA2213 
} 

public sealed class Bad : IDisposable { 
    public Font Font { get; set; } 
    public Bad() { Font = new Font("Arial", 9); } 
    public void Dispose() { /* Do nothing */ }  // No warning 
} 

किसी और को इस व्यवहार का सामना करना पड़ा है? क्या यह CA2213 नियम में डिज़ाइन या बग द्वारा है?

उत्तर

0

स्टेटिक विश्लेषण उपकरण बहुत सारे झूठी-सकारात्मक उत्पन्न करने के बीच एक अच्छे व्यापार-बंद के लिए ट्यून किए गए हैं (यानी पूरी तरह से ठीक कोड पर मुद्दों को छोड़कर) और बहुत से झूठे-नकारात्मक (यानी कोड में वास्तविक समस्याएं गायब हैं)।

के एक सरल उदाहरण लेते हैं:

// CA2213 detects an issue 
class OwnsTheField : IDisposable 
{ 
    private MemoryStream f = new MemoryStream(); 
    public void Dispose() {} 
} 

यह इस मामले कि एक मुद्दा सूचित किया जाना चाहिए में स्पष्ट है, और कहा कि वास्तव में मामला है।

अब, चलो बातें थोड़ा और अधिक जटिल बनाते हैं:

// CA2213 does not detect 
class FieldIsInjected : IDisposable 
{ 
    private MemoryStream f; 
    public FieldIsInjected(MemoryStream p) 
    { 
     f = p; 
    } 
    public void Dispose() { } 
} 

इस मामले में, वहाँ निपटान नहीं f साथ एक मुद्दा नहीं हो सकता है। यदि p ठीक से कॉल करने वाले को निपटान किया जाता है, तो सब कुछ के रूप में की उम्मीद काम करता है:

using (var p = new MemoryStream()) 
{ 
    using (var x = FieldIsInjected(p)) { /* ... */ } 
} // p is properly disposed 
प्रायः

, (सभी कोने मामलों से निपटने सहित) सही व्यवहार दर्ज नहीं किया जाएगा, के रूप में एक संपूर्ण प्रलेखन होगा समय के साथ बनाए रखने के लिए बहुत महंगा है। उदाहरण के लिए, इस अपवाद को स्पष्ट रूप से https://msdn.microsoft.com/en-us/library/ms182328.aspx

+0

यदि आप सूचीबद्ध करते हैं, तो कोड विश्लेषण में अभी भी आपको कुछ तरीकों से 'f' को संभालने की आवश्यकता होती है, आमतौर पर मैन्युअल रूप से दबाने से और इंजेक्शन फ़ील्ड वर्तमान वर्ग के स्वामित्व में नहीं है। यह मेरे लिए एक अच्छा समाधान है। एक अच्छा समाधान क्या नहीं है, कोड विश्लेषण समस्या बिल्कुल नहीं दिखा रही है, क्योंकि केवल 'एफ' एक ऑटोप्रोपर्टी है या क्योंकि फील्डआई इंजेक्शन एक आईडीस्पोजेबल क्लास से निकला है और ओवरराइड नहीं करता है (बूल) –

0

नियम .net framework 2 से है, और auto properties are from C# 3, जो भाषा विनिर्देश को जोड़ा गया है के बाद नियम बनाया गया था में बताया गया है। नियम नहीं क्षेत्रों गुणों के संदर्भ में परिभाषित किया गया है, तो ऐसा लगता है जैसे कि यह एक अद्यतन के लिए की वजह से है, लेकिन जैसा कि वर्तमान में निर्दिष्ट काम कर रहे।

This Question on disposing properties दिखाता है कि IDisposable लागू करने वाले गुण ढांचे में संगत नहीं हैं।

4

कोड विश्लेषक सीमाएं होती हैं, इस कोड में एक वर्तमान है कि यह एक क्रियान्वित होने चेतावनी उत्पन्न करने के लिए की जरूरत है। एक प्रोग्रामर वास्तव में अपने कोड को ठीक करने के लिए आगे बढ़ सकता है। वर्तमान कोड विश्लेषक के साथ एक प्रमुख समस्या यह विधानसभा कि संकलक द्वारा उत्पन्न से काम करता है, कि यह स्रोत कोड का विश्लेषण नहीं करता है। जो अच्छा है, यह किसी भी .NET भाषा के लिए काम करता है। लेकिन कोई भी इस चेतावनी की तरह होगा:

CA2213 डिस्पोजेबल क्षेत्रों निपटारा किया जाना चाहिए
'बैड' फ़ील्ड <Font>k__BackingField IDisposable प्रकार की है कि शामिल हैं: 'फ़ॉन्ट'। इस क्षेत्र पर निपटान या बंद करने के लिए 'खराब' पर निपटान विधि बदलें।

यद्यपि, कार्यक्रम में ऐसा कोई क्षेत्र नहीं है। एक बेहतर संदेश उत्पन्न करने के लिए, विश्लेषक को यह पता लगाना होगा कि मेटाडेटा में <Font>k__BackingField फ़ील्ड वास्तव में ऑटो-लागू Font संपत्ति से जुड़ा हुआ है। मेटाडेटा में कुछ भी उपलब्ध नहीं है जो उस कनेक्शन को अनजाने में बनाता है। फ़ील्ड में केवल [कंपाइलर जेनरेटेड] विशेषता होती है और ऑटो-जेनरेटेड फ़ील्ड नाम एक कंपाइलर कार्यान्वयन विवरण होता है। विभिन्न भाषा संकलक विभिन्न नाम उत्पन्न करते हैं।

यह ऐसी समस्या है जिसके लिए स्रोत-कोड विश्लेषण की आवश्यकता होती है, आईएल विश्लेषण वर्तमान में लागू नहीं किया गया है। अवसर दरवाजे पर दस्तक दे रहा है, स्रोत-कोड विश्लेषण आज उपलब्ध रोज़लिन के साथ लागू करना बहुत आसान होगा। वीएस2015 पहला वीएस संस्करण है जो "लाइव कोड" विश्लेषण का समर्थन करता है। मुझे अभी तक पता नहीं है कि यह जल्द ही सीए 2213 स्टाइल त्रुटियों की तलाश में है या नहीं।

+0

क्या कोई समाधान है जो काम कर सकता है VS2012? जैसे स्टाइलकॉप नियम जो ऑटोप्रॉपर्टीज पर ट्रिगर करता है जो आईडीस्पोजेबल से प्राप्त होता है? –

+0

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

+0

मैं सहमत हूं, समाधान सीधे आगे नहीं है। स्रोत कोड का विश्लेषण करते समय जितना संभव हो उतना मामला कवर करने के लिए (और हमारे वीसीएस में खराब कोड को रोकने के लिए), मैं अलग-अलग दृष्टिकोण जोड़ता हूं: स्रोत कोड विश्लेषण (स्टाइलकॉप), आईएल विश्लेषण (एफएक्सकॉप), प्रतिबिंब के साथ यूनिट परीक्षण (नियमों को मजबूर करने के लिए विशिष्ट प्रकारों पर), अतिरिक्त प्रोग्राम कोड (जो केवल डीबग बिल्ड में या डीबगर संलग्न होने पर निष्पादित होता है) और कस्टम पावरशेल स्क्रिप्ट्स। बेशक गेटेड चेक-इन सक्षम हैं और वह सब कुछ करें। – Zvonko

0

विश्लेषण इंजन संपत्ति और उसके समर्थन क्षेत्र के बीच चलने में पूरी तरह से सक्षम है। इसमें बस ऐसा करने का तर्क नहीं है, और इसलिए चेतावनी के अवसर को याद आती है। इससे भी बदतर, यह एक false warning उत्सर्जित करता है यदि एक उचित तरीके से निपटान संपत्ति केवल प्राप्त होती है।

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