2008-10-04 12 views
317

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

+17

क्या रिशर्पर वास्तव में "कम-संयोजन, कम-संयोजन" चिल्ला रहा है? यह देखने का समय है कि विधि वास्तव में उस वर्ग से संबंधित है या नहीं। –

+1

[संभावित स्टेटिक तरीकों का उपयोग करने के लाभ] के संभावित डुप्लिकेट [http://stackoverflow.com/questions/135020/advantages-to-using-private-static-methods) – drzaus

उत्तर

215

बनाम उदाहरण तरीकों
सी # भाषा विशिष्टता की 10.2.5 Static and instance members स्टेटिक तरीकों अंतर बताते हैं। आम तौर पर, स्थिर विधियां उदाहरण विधियों पर बहुत कम प्रदर्शन वृद्धि प्रदान कर सकती हैं, लेकिन केवल कुछ चरम स्थितियों में (this answer देखें कि इसके बारे में कुछ और विवरण)। FxCop या कोड विश्लेषण में

नियम CA1822 राज्यों:

"[अंकन स्थिर के रूप में सदस्यों], संकलक इन सदस्यों जिसके लिए रनटाइम पर एक चेक कर पाएगा करने के लिए गैर आभासी कॉल साइटों उत्सर्जित करेगा के बाद प्रत्येक ऑब्जेक्ट जो वर्तमान ऑब्जेक्ट पॉइंटर को सुनिश्चित करता है गैर-शून्य है। इसके परिणामस्वरूप प्रदर्शन-संवेदनशील कोड के लिए एक मापनीय प्रदर्शन लाभ हो सकता है। कुछ मामलों में, वर्तमान ऑब्जेक्ट इंस्टेंस तक पहुंचने में विफलता एक शुद्धता समस्या का प्रतिनिधित्व करती है। "

उपयोगिता कक्षा
आप उन्हें एक उपयोगिता वर्ग के लिए कदम नहीं करना चाहिए जब तक यह अपने डिजाइन में समझ में आता है। यदि स्थैतिक विधि किसी विशेष प्रकार से संबंधित है, जैसे ToRadians(double degrees) विधि कोणों का प्रतिनिधित्व करने वाली कक्षा से संबंधित है, तो उस विधि के उस स्थिर सदस्य के रूप में मौजूद होने के लिए यह विधि समझती है (नोट, यह प्रदर्शन के उद्देश्यों के लिए एक संक्षिप्त उदाहरण है) ।

+2

> कंपाइलर इन सदस्यों को गैर वर्चुअल कॉल साइट्स को उत्सर्जित करेगा असल में यह है कि "कंपाइलर उत्सर्जित हो सकता है ..."। मुझे कुछ संभावित बग के आसपास काम करने के लिए कॉल के बजाय कॉलवर्ट का उपयोग कर सी # कंपाइलर के बारे में कुछ याद है। –

+22

मैं इसे सीधे FxCop 1.36 से काट और पेस्ट करता हूं। यदि FxCop गलत है, तो काफी उचित है। –

+5

@ मैक्सिम यकीन नहीं है कि मैं "बकवास" कथन की सराहना करता हूं; अजनबियों से संपर्क करने के लिए बहुत कठोर तरीका। हालांकि, अंतर्निहित बिंदु मान्य है; मैंने चीजों को थोड़ा सा अद्यतन किया है (यह 9 साल पहले था, इसलिए मुझे अपने मूल दावे की नींव याद नहीं है)। –

2

यह नामस्थान प्रदूषण को नियंत्रित करने में मदद करता है।

+8

विधि विधि सहायता कैसे नामस्थान प्रदूषण से बचती है? – lockstock

+1

अनुभव से, स्थैतिक तरीकों वाले वर्गों में विधियों को समूहीकृत करके, आप ढीले कार्यों के सभी "हथियार बैग" को उपसर्ग करने के अनुभव से परहेज कर रहे हैं जो अन्य लाइब्रेरी या अंतर्निहित कार्यों के साथ संघर्ष कर सकते हैं। स्थैतिक तरीकों के साथ, वे कक्षा नाम के तहत प्रभावी रूप से नामित हैं, पूर्व। 'Class.a_core_function (..) 'बनाम' a_core_function (..)' – lintuxvi

5

आपको किसी दिए गए परिदृश्य में सबसे अधिक पढ़ने योग्य और सहज ज्ञान युक्त करना चाहिए।

प्रदर्शन तर्क सबसे चरम स्थितियों को छोड़कर एक अच्छा नहीं है क्योंकि वास्तव में एकमात्र चीज यह है कि एक अतिरिक्त पैरामीटर (this) उदाहरण विधियों के लिए स्टैक पर धकेल रहा है।

2

यदि फ़ंक्शंस कई पृष्ठों पर साझा किए जाते हैं, तो आप उन्हें बेस पेज क्लास में भी डाल सकते हैं, और फिर उस कार्यक्षमता का उपयोग करके सभी एएसपीनेट पेजों को प्राप्त कर सकते हैं (और फ़ंक्शंस अभी भी स्थैतिक हो सकते हैं)।

19

मुझे यकीन है कि यह आपके मामले में नहीं हो रहा है, लेकिन कुछ कोड में मैंने देखा है कि "खराब गंध" मुझे बहुत सारी स्थिर विधियों का उपयोग करने के लिए पीड़ित होना पड़ा है।

दुर्भाग्यवश, वे स्थिर तरीके थे जो एक विशेष आवेदन स्थिति मानते थे। (क्यों सुनिश्चित करें, हमारे पास प्रति एप्लिकेशन केवल एक उपयोगकर्ता होगा! क्यों उपयोगकर्ता वर्ग स्थिर वैरिएबल में इसका ट्रैक रखता है?) वे वैश्विक चरों तक पहुंचने के तरीकों की महिमा कर रहे थे। उनके पास स्थैतिक रचनाकार भी थे (!), जो लगभग हमेशा एक बुरा विचार है। (मुझे पता है कि कुछ उचित अपवाद हैं)।

हालांकि, जब वे डोमेन-तर्क को कारक करते हैं तो स्थिर विधियां काफी उपयोगी होती हैं जो वास्तव में वस्तु के उदाहरण की स्थिति पर निर्भर नहीं होती हैं। वे आपके कोड को और अधिक पठनीय बना सकते हैं।

बस सुनिश्चित करें कि आप उन्हें सही जगह पर डाल रहे हैं। क्या स्थिर तरीके अन्य वस्तुओं की आंतरिक स्थिति को घुसपैठ कर रही हैं?क्या एक अच्छा मामला बन सकता है कि उनका व्यवहार इसके बजाय उन वर्गों में से एक से संबंधित है? यदि आप चिंताओं को सही तरीके से अलग नहीं कर रहे हैं, तो आप बाद में सिरदर्द में हो सकते हैं।

+0

आपकी समस्या स्थैतिक फ़ील्ड/गुणों के साथ है, स्थिर तरीकों से नहीं। –

46

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

2

एक विधि स्थिर बनाना मतलब है कि आप कक्षा के बाहर से उस वर्ग का उदाहरण बनाये बिना विधि को कॉल कर सकते हैं। तृतीय पक्ष विक्रेता ऑब्जेक्ट्स या एड-ऑन के साथ काम करते समय यह सहायक होता है। कल्पना कीजिए कि अगर आपको पहले कंसोल ऑब्जेक्ट "कॉन" बनाना था, तो con.wreline();

233

प्रदर्शन, नामस्थान प्रदूषण आदि मेरे विचार में सभी माध्यमिक हैं। खुद से पूछें कि तार्किक क्या है। विधि विधि के उदाहरण पर तार्किक रूप से चल रही है, या यह स्वयं से संबंधित है? यदि यह उत्तरार्द्ध है, तो इसे एक स्थिर विधि बनाएं। केवल इसे एक उपयोगिता वर्ग में ले जाएं यदि यह किसी ऐसे प्रकार से संबंधित है जो आपके नियंत्रण में नहीं है।

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

+0

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

6

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

6

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

दूसरी ओर यह उपयोगिता विधियों के प्रसार द्वारा प्रदूषित एक वर्ग का कारण बन सकता है। हमेशा के रूप में, लॉजिकल नामकरण, दस्तावेज, और टीम कोडिंग सम्मेलनों के लगातार आवेदन इस को कम कर सकते हैं।

5

ReSharper तर्क की जांच नहीं करता है। यह केवल जांच करता है कि विधि उदाहरण सदस्यों का उपयोग करती है या नहीं। यदि विधि निजी है और केवल (केवल एक ही) उदाहरण विधियों द्वारा बुलाया जाता है तो यह एक उदाहरण विधि देने के लिए एक संकेत है।

6

यह दिलचस्प पढ़ा है:

http://thecuttingledge.com/?p=57

ReSharper वास्तव में आप अपने विधि स्थिर बनाने के सुझाव नहीं है। आप अपने आप से पूछना चाहिए क्यों कि विधि है कि वर्ग के रूप में, वर्गों है कि उसके हस्ताक्षर में दिखाई देता है से एक के लिए, कहते हैं का विरोध में है ...

लेकिन यहाँ क्या ReSharper documentaion कहते है: http://confluence.jetbrains.net/display/ReSharper/Member+can+be+made+static

+0

मुझे लगता है कि यह बिंदु अंतर्निहित है। उपकरण वास्तव में आपको क्या बता रहा है कि यह विधि केवल कुछ अन्य वर्ग के सदस्यों पर ही चलती है। अगर यह किसी प्रकार का कमांड (या "केस केस" या "इंटरैक्टर") ऑब्जेक्ट है, तो जिम्मेदारी कौन है अन्य ऑब्जेक्ट्स में हेरफेर करना, यह ठीक है। हालांकि, अगर यह केवल एक अन्य वर्ग में हेरफेर करता है जो [फ़ीचर ईर्ष्या] (http://wiki.c2.com/?FeatureEnvySmell) जैसा लगता है। – Greg

0

बस मेरी tuppence: एक उपयोगिता वर्ग के लिए साझा स्थिर तरीकों के सभी शामिल करने से आपकी का उपयोग कर बयान है, जो कोड तेजी से टाइप करें और पढ़ने में आसान करने के लिए बनाता है

using static className; 

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

मुझे नहीं पता कि यह अच्छा अभ्यास है या नहीं। मुझे सी # 4/5 के बारे में जानने के लिए बहुत कुछ है और इतने सारे विरासत कोड को रिफैक्टर करने के लिए कि मैं बस Roselyn युक्तियों को मुझे मार्गदर्शन करने की कोशिश कर रहा हूं।

जोय

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