2009-04-08 5 views
24

जब एक क्षेत्र (यहाँ एक bool करने के लिए गलत) करने के लिए डिफ़ॉल्ट डिफ़ॉल्ट-मान निर्दिष्ट, FxCop का कहना है:FxCop क्यों फ़ील्ड को डिफ़ॉल्ट मान पर प्रारंभ करना गलत लगता है?

Resolution : "'Bar.Bar()' initializes field 'Bar.foo' 
       of type 'bool' to false. Remove this initialization 
       because it will be done automatically by the runtime." 

अब, मैं int a = 0 या bool ok = false के रूप में है कि कोड कुछ अतिरेक पेश कर रहा है पता है, लेकिन मेरे लिए यह लगता है एक बहुत ही अच्छा कोड-अभ्यास, एक ऐसा जो कि मेरे शिक्षकों ने मेरी राय में ईमानदारी से जोर दिया।

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

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

क्या FxCop यहां एक स्पष्ट गलती कर रहा है, या इसके लिए और भी कुछ है?

दो अपडेट:

  1. यह सिर्फ मेरी राय है, लेकिन क्या मैं विश्वविद्यालय (बेल्जियम) में सिखाया गया है नहीं है। ऐसा नहीं है कि मैं argumentum ad verecundiam का उपयोग करना चाहता हूं, लेकिन यह दिखाने के लिए कि यह सिर्फ मेरी राय नहीं है। और के विषय में है कि:

  2. मेरे क्षमायाचना, मैं सिर्फ इस एक पाया:

    Should I always/ever/never initialize object fields to default values?

+0

मुझे नहीं लगता कि प्रारंभिकरण को कम करने से भी एक प्रदर्शन लाभ है। –

+0

मैं मार्टिनो से सहमत हूं, लेकिन मुझे आपका प्रश्न पसंद है! –

+1

@ मार्टिन्हो फर्नांडीस: इसे छोड़ने के लिए एक प्रदर्शन लाभ है - मेरा उत्तर और आलेख संदर्भित देखें। –

उत्तर

12

वहाँ कुछ मामलों में, इस से महत्वपूर्ण प्रदर्शन लाभ हो सकता है। विवरण के लिए, see this CodeProject article.

मुख्य मुद्दा यह है कि यह सी # में अनावश्यक है। सी ++ में, चीजें अलग होती हैं, इसलिए कई प्रोफेसर सिखाते हैं कि आपको हमेशा प्रारंभ करना चाहिए। वस्तुओं को शुरू करने के तरीके को .NET में बदल दिया गया है।

.NET में, वस्तुओं को हमेशा बनाए जाने पर प्रारंभ किया जाता है। यदि आप प्रारंभकर्ता जोड़ते हैं, तो यह संभव है (सामान्य) कि आप अपने चर के दोहरा प्रारंभिक कारण बनते हैं। ऐसा होता है कि क्या आप उन्हें कन्स्ट्रक्टर या इनलाइन में प्रारंभ करते हैं।

इसके अतिरिक्त, प्रारंभिक होने के बाद .NET में अनावश्यक है (यह हमेशा होता है, भले ही आप डिफ़ॉल्ट रूप से प्रारंभ करने के लिए स्पष्ट रूप से नहीं कहें), एक प्रारंभिकता जोड़ना, एक पठनीयता दृष्टिकोण से, जो आप जोड़ने की कोशिश कर रहे हैं कोड जिसमें एक समारोह है। कोड के प्रत्येक टुकड़े का उद्देश्य होना चाहिए, या अनावश्यक होने पर हटा दिया जाना चाहिए। "अतिरिक्त" कोड, भले ही यह हानिरहित था, सुझाव देता है कि यह एक कारण के लिए है, जो रखरखाव को कम करता है।

+2

कौन या किसके लिए अनावश्यक? आप निश्चित रूप से व्यक्तियों के लिए कोड, मशीन टिप्पणियों के लिए अनावश्यक भी हैं, इसका मतलब यह नहीं है कि वे अनावश्यक perse – Peter

+0

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

+1

एक टिप्पणी के साथ अंतर, जब मैं int i = 0 कहता हूं; मैं चाहता हूं कि मैं शून्य हो, बयान तार्किक है। यहां तक ​​कि जब भविष्य के कंपाइलर के साथ संकलित किया गया है जिसमें अन्य डिफ़ॉल्ट (intccourse के लिए असंभव) – Peter

2

यह किसी भी समय स्थानीय रूप से परिभाषित "कॉर्पोरेट मानक" को जानने वाले हर प्रोग्रामर पर निर्भर नहीं है जो किसी भी समय बदल सकता है, लेकिन मानक रूप से मानक में परिभाषित कुछ पर। आप यह भी कह सकते हैं "x++ का उपयोग न करें क्योंकि यह प्रत्येक प्रोग्रामर के ज्ञान पर निर्भर करता है।

+0

पूरी तरह से अलग-अलग मुद्दों आईएमओ, (बीच() में डेटटाइम डिफ़ॉल्ट है, और इसका मूल्य क्या है? X-- क्या करता है? मुझे लगता है कि प्रोग्रामर के बाद के 100% का जवाब पता है, पहले का जवाब - अगर हम भाग्यशाली हैं - 50%) – Peter

+0

सबसे पहले, यह "डिफ़ॉल्ट (दिनांक समय)" के बराबर है। दूसरा, आप किस परिस्थिति में वास्तविक मूल्य की परवाह करेंगे? –

2

आपको याद रखना होगा कि FxCop नियम केवल दिशानिर्देश हैं, वे अटूट नहीं हैं। यह भी कहते हैं तो नियम आप का उल्लेख के विवरण के लिए पेज (http://msdn.microsoft.com/en-us/library/ms182274(VS.80).aspx, जोर मेरा) पर:

जब चेतावनी को निकालना है:

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

अब, नियम पूरी तरह गलत नहीं है, लेकिन जैसा कि यह कहता है, यह आपके लिए प्राथमिकता नहीं है, इसलिए नियम को अक्षम करें।

3

एफएक्स पुलिस इसे अनावश्यक कोड जोड़ने के रूप में देखता है और अनावश्यक कोड खराब है। मैं आपसे सहमत हूं, मुझे यह देखना पसंद है कि यह क्या सेट है, मुझे लगता है कि यह पढ़ना आसान बनाता है।

ऐसा ही एक समस्या हम मुठभेड़ है, प्रलेखन कारणों से हम इस

/// <summary> 
/// a test class 
/// </summary> 
/// <remarks>Documented on 4/8/2009 by richard</remarks> 
public class TestClass 
{ 
    /// <summary> 
    /// Initializes a new instance of the <see cref="TestClass"/> class. 
    /// </summary> 
    /// <remarks>Documented on 4/8/2009 by Bob</remarks> 
    public TestClass() 
    { 
     //empty constructor 
    }   
} 

संकलक स्वचालित रूप से इस निर्माता बनाता है की तरह एक खाली निर्माता बना सकते हैं, FX पुलिस में शिकायत लेकिन हमारे सैंडकैसल प्रलेखन नियमों के सभी सार्वजनिक तरीकों की आवश्यकता होती है तो दस्तावेज किया जाना चाहिए, इसलिए हमने केवल एफएक्स पुलिस को बताया कि इसके बारे में शिकायत न करें।

+0

अनावश्यक कोड निश्चित रूप से खराब है, लेकिन यह कोड असंभव घटना में आवश्यक हो सकता है, भविष्य में एक डिफ़ॉल्ट बदल दिया जाएगा और यह कोड पुनः संकलित किया जाएगा। – Peter

+0

@ पीटर: मूल्य प्रकारों के लिए डिफ़ॉल्ट हमेशा शून्य के लिए प्रारंभ करने की गारंटी है। यह सीएलआर विनिर्देश का हिस्सा है। मूल्य प्रकार डिफ़ॉल्ट बदलने के लिए कोई रास्ता नहीं है। संदर्भ प्रकार समान हैं - उन्हें सटीक रूप से, डिफ़ॉल्ट रूप से, डिफ़ॉल्ट रूप से गारंटी दी जाती है। –

+0

@ बॉब जेनिटर, ऐसी चीजें कर रहा है जो सिर्फ एक उपकरण को संतुष्ट करने के लिए सही महसूस नहीं करते हैं, आमतौर पर खराब होता है! ;) –

5

FxCop को सभी के लिए नियम प्रदान करना है, इसलिए यदि यह नियम आपको अपील नहीं करता है, तो बस इसे बाहर कर दें।

अब, मैं सुझाव दूंगा कि यदि आप स्पष्ट रूप से डिफ़ॉल्ट मान घोषित करना चाहते हैं, तो इसे करने के लिए निरंतर (या स्थैतिक रीडोनली चर) का उपयोग करें। यह मूल्य के साथ शुरू करने से भी स्पष्ट होगा, और FXCop शिकायत नहीं करेगा।

private const int DEFAULT_AGE = 0; 

private int age = 0; // FXCop complains 
private int age = DEFAULT_AGE; // FXCop is happy 

private static readonly DateTime DEFAULT_BIRTH_DATE = default(DateTime); 

private DateTime birthDate = default(DateTime); // FXCop doesn't complain, but it isn't as readable as below 
private DateTime birthDate = DEFAULT_BIRTH_DATE; // Everyone's happy 
+0

टीएक्स (एक पूर्व टिप्पणी में भी सुझाव दिया गया था) – Peter

5

Reed Copsey said क्षेत्रों प्रभावों प्रदर्शन के लिए डिफ़ॉल्ट मान को निर्दिष्ट, और वह a test from 2005 को दर्शाता है।

public class A 
{ 
    // Use CLR's default value 
    private int varA; 
    private string varB; 
    private DataSet varC; 
} 

public class B 
{ 
    // Specify default value explicitly 
    private int varA = 0; 
    private string varB = null; 
    private DataSet varC = null; 
} 

अब आठ साल और सी # और .NET के चार संस्करण बाद में मैं .NET फ्रेमवर्क 4.5 और सी # 5, डिफ़ॉल्ट अनुकूलन के साथ रिलीज के रूप में संकलित के तहत है कि परीक्षण दोहराने के लिए दृश्य स्टूडियो 2012 का उपयोग कर रहा देख कर हैरान था फैसला किया कि उनके डिफ़ॉल्ट मानों के साथ फ़ील्ड को स्पष्ट रूप से प्रारंभ करने और डिफ़ॉल्ट मान निर्दिष्ट नहीं करने के बीच अभी भी एक प्रदर्शन अंतर है। मैं बाद में सी # कंपाइलर्स को उन निरंतर असाइनमेंट को ऑप्टिमाइज़ करने की अपेक्षा करता था।

 
No init: 512,75 Init on Def: 536,96 Init in Const: 720,50 
Method No init: 140,11 Method Init on Def: 166,86 

(the rest)

तो मैं वर्गों A और इस परीक्षण में B की कंस्ट्रक्टर्स अंदर peeked, और दोनों खाली हैं:

.method public hidebysig specialname rtspecialname 
    instance void .ctor() cil managed 
{ 
    // Code size 7 (0x7) 
    .maxstack 8 

    IL_0000: ldarg.0 
    IL_0001: call instance void [mscorlib]System.Object::.ctor() 
    IL_0006: ret 
} // end of method .ctor 

मैं कर सकता नहीं आईएल में एक कारण ढूंढें क्यों फ़ील्ड में स्पष्ट रूप से डिफ़ॉल्ट निरंतर मान निर्दिष्ट करते हैं अधिक समय लगता है। स्पष्ट रूप से सी # कंपाइलर स्थिरांक को अनुकूलित करता है, और मुझे संदेह है कि यह हमेशा किया जाता है।

तो, परीक्षण गलत होना चाहिए ... मैंने वर्गों की सामग्री को A और B की सामग्री बदल दी, परिणाम स्ट्रिंग में संख्याओं को बदल दिया, और परीक्षणों को फिर से चलाया। और लो और देखें अब अचानक डिफ़ॉल्ट मान निर्दिष्ट करना है।

 
No init: 474,75 Init on Def: 464,42 Init in Const: 715,49 
Method No init: 141,60 Method Init on Def: 171,78 

(the rest)

इसलिए मैं निष्कर्ष है कि सी # संकलक सही ढंग से इस मामले में जहां आप क्षेत्रों के लिए डिफ़ॉल्ट मान निर्दिष्ट के लिए अनुकूलित करता है। इससे कोई प्रदर्शन अंतर नहीं होता है!


अब हम जानते हैं कि प्रदर्शन वास्तव में नहीं एक मुद्दा है। और मैं Reed Copsey's statement से असहमत "'अतिरिक्त' कोड, भले ही यह हानिरहित था, चलता है कि यह एक कारण है, जो रख-रखाव की कम कर देता है के लिए है।" और Anders Hansson इस पर सहमत:

दीर्घकालिक सोचो रखरखाव।

  • कोड को यथासंभव स्पष्ट रखें।
  • यदि आपको ऐसा करने की आवश्यकता नहीं है तो आरंभ करने के लिए भाषा विशिष्ट तरीकों पर भरोसा न करें। शायद भाषा का एक नया संस्करण अलग-अलग काम करेगा?
  • भविष्य प्रोग्रामर आपको धन्यवाद देंगे।
  • प्रबंधन आपको धन्यवाद देगा।
  • चीजों को थोड़ी सी भी परेशान क्यों करें?

भविष्य के रखरखाव एक अलग पृष्ठभूमि से आ सकते हैं। यह वास्तव में "सही" के बारे में नहीं है, यह लंबे समय तक सबसे आसान होगा।

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

  • कोई संबंधित समस्या नहीं^_^