आंशिक कक्षाओं का उपयोग क्यों करें?


72

मेरी समझ में, partialकीवर्ड कुछ भी नहीं करता है लेकिन एक वर्ग को कई स्रोत फ़ाइलों के बीच विभाजित करने की अनुमति देता है। क्या कोड संगठन के अलावा ऐसा करने का कोई कारण है? मैंने इसे यूआई कक्षाओं में इसके लिए इस्तेमाल किया है।

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


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

4
यदि आप उनका उपयोग करते हैं, और यह उत्पन्न कोड के लिए नहीं है, तो मुझे आपसे नफरत है। आप व्यक्तिगत रूप से नहीं, लेकिन आप आम तौर पर। मुझे आंशिक वर्गों के माध्यम से कोड के शिकार से नफरत है।
स्टीवन एवर्स

3
"हंट डाउन कोड" के लिए यह मुश्किल नहीं है, सभी वर्ग विधियां अभी भी वीएस में ड्रॉप डाउन में दिखाई देती हैं, भले ही आप जिस भाग को देख रहे हैं, वह किस हिस्से में है। अन्य कोड नेविगेशन भी ठीक काम करता है (या तो "चतुर" R # शैली नेविगेशन या अच्छा पुरानी पारी- ctrl-f
स्टीव

2
यह गलतफहमी है कि आंशिक वर्गों को अलग-अलग फाइलों में रहना पड़ता है।
बार्ट

जवाबों:


110

यह प्रत्येक परिदृश्य में बहुत उपयोगी होता है जहाँ वर्ग का एक हिस्सा किसी न किसी कस्टम टूल द्वारा उत्पन्न किया जाता है क्योंकि यह आपको जेनरेट किए गए कोड को उत्पन्न किए बिना कस्टम लॉजिक को कोड में जोड़ने की अनुमति देता है। Btw। उसी कारण से आंशिक तरीके भी हैं।

यह न केवल यूआई के बारे में है, बल्कि अन्य प्रौद्योगिकियां जैसे कि लिनक-टू-सक्ल या एंटिटी फ्रेमवर्क भी इसका काफी उपयोग करते हैं।


44
इसके अलावा, यह आपको अपने कोड को संस्करण नियंत्रण से बाहर रखने के दौरान संस्करण नियंत्रण के तहत रखने देता है।
फ्रैंक शियरर

3
अच्छी बात है, मैंने ऐसा कभी नहीं सोचा था। मैंने केवल अभ्यास में इसका दुरुपयोग होते देखा है। फ़ाइल आकार प्रबंधनीय रखने के लिए (घटिया) प्रोग्रामर के लिए एक तरीका।
मार्टिन विकमैन

1
मेरे द्वारा उपयोग किए जाने वाले सर्वोत्तम उदाहरण हैं: ए) लाइनक से एसक्यूएल डेटा संदर्भों के लिए जहां आप कक्षाओं का विस्तार करना चाहते हैं; बी) वेब सेवाओं से उत्तीर्ण कक्षाओं का विस्तार करने के लिए। न तो मामले में यह एक दुरुपयोग है और न ही यह फ़ाइल आकार को प्रबंधनीय रखने का एक साधन है ... मैं इसे इस तरह से इस्तेमाल करते हुए देखने के लिए मौलिक रूप से दुखी होऊंगा (और कदम
उठाऊंगा

3
WinForm क्लासेस इसे बनाने वाले सभी डिज़ाइनर कोड कंट्रोल को छिपाने के लिए उपयोग करते हैं (विशेष रूप से महत्वपूर्ण क्योंकि डिजाइनर बेतरतीब ढंग से सभी कोड को फिर से व्यवस्थित करना पसंद करता है जिसके परिणामस्वरूप बहुत बड़ी गड़बड़ियाँ होती हैं जब diff / blaming), और यदि आप XML के साथ काम कर रहे हैं, तो XSD टूल कर सकते हैं स्कीमा फ़ाइल से आंशिक कक्षाएं फिर से बनाएं ताकि आप अपने कोड को ऑटो जेनरेट किए गए सॉर्ट से अलग कर सकें।
डैन नीली

2
@MartinWickman जरूरी नहीं कि घटिया हो। यह विरासत कोड में भगवान की वस्तुओं को फिर से दिखाने के लिए एक अच्छा प्रारंभिक बिंदु है। पहले अलग-अलग फ़ाइलों में बड़ी कक्षाओं को विभाजित करके परिदृश्य को साफ़ करने का प्रयास करें। (मुझे पता है कि आपकी टिप्पणी बहुत पुरानी है)
कोनराड मोरव्स्की

26

जैसा कि आप कहते हैं, इसका उपयोग अक्सर उत्पन्न कोड को अलग करने के लिए किया जाता है। यह अक्सर कक्षाओं / फ़ाइलों के आकार के साथ कुछ नहीं करना है।

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

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


9
मैंने इंटरफ़ेस कार्यान्वयन को अलग करने के लिए श्रेणी के भाग का उपयोग करने के बारे में कभी नहीं सोचा था, यह एक उत्कृष्ट विचार है।
मार्क बूथ

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

19

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

हालाँकि, सामान्य तौर पर मुझे लगता है कि उन्हें नए कोड लिखते समय केवल मशीन से उत्पन्न कक्षाओं को बढ़ाने के लिए उपयोग किया जाना चाहिए।


1
मैं देख सकता हूं कि यह कैसे उपयोगी हो सकता है। इसके लिए भाषा में होना उचित है या नहीं ... मुझे नहीं पता। मशीन ने कोड की एक और कहानी उत्पन्न की, हालांकि।
माइकल के

2
हां, भाषा में इसका होना कोई औचित्य नहीं है, लेकिन यह उनका उपयोग करने का एक दिलचस्प तरीका है।

18

मैं कुछ उपयोगी परिदृश्यों के बारे में सोच सकता हूँ जहाँ पर धारावाहिकों का अर्थ होता है, उनमें से अधिकांश का उपयोग मैं स्वयं अपनी परियोजनाओं में कर रहा हूँ:

  • आपके द्वारा बनाए गए कोड से टूल / आईडीई / डिज़ाइनर जनरेट किए गए कोड को अलग करने के लिए । एक अच्छा उदाहरण वह Form.Designer.csफ़ाइल है जिसमें विंडोज़ रूपों के अनुप्रयोगों के लिए डिज़ाइनर कोड उत्पन्न होता है। कई अन्य .NET प्रारूपों में भी कुछ उपकरण उत्पन्न कोड होते हैं, जिन्हें आप अपनी परियोजना बनाते समय संभावित रूप से पुनर्जीवित कर सकते हैं, और इस प्रकार आपके सभी कस्टम परिवर्तन नष्ट हो जाएंगे। पृथक्करण आपके कोड और परिवर्तनों को ऐसे स्वचालित संशोधनों से सुरक्षित रखने में आपकी सहायता करेगा।

  • जब आप कार्यान्वयन में बहुत सारे कोड के साथ कई इंटरफेस लागू कर रहे हैं । मैं इस तरह के नामकरण, प्रत्येक ऐसे इंटरफ़ेस के लिए एक अलग आंशिक फ़ाइल का उपयोग करता हूं {Class}.{Interface}.cs:। मेरे लिए आईडीई में यह देखना आसान है कि कौन सा इंटरफेस {Class}लागू कर रहा है और कैसे।

  • जब कक्षा में एक या एक से अधिक नेस्टेड कक्षाएं होनी चाहिए , विशेष रूप से उनमें पर्याप्त कोड के साथ एक अलग फ़ाइल में डाल दिया जाए। मैं उपरोक्त पैटर्न पर {Class}.{NestedClass}.csटिकूंगा और प्रत्येक नेस्टेड क्लास के लिए नामकरण सम्मेलन का उपयोग करूंगा । इसी तरह के अभ्यास का उल्लेख पहले से ही वर्टिलिंक के उत्तर द्वारा किया गया है ।

  • जब मैं staticकक्षाएं लिखता हूं जो विस्तार के तरीकों का आयोजन करेगा । यह अक्सर समान वर्गों या इंटरफेस के लिए एक ही एक्सटेंशन विधि तर्क प्रदान करने के लिए मामला होगा - जैसे Reverseकि सामान्य और गैर-सामान्य संग्रह पर उदाहरण के लिए । मैं एक एकल वर्ग या इंटरफ़ेस के लिए सभी विस्तार विधियों को स्थिर वर्ग के एक अलग हिस्से में रखूँगा। उदाहरण के लिए, मेरे पास IListएक स्थान पर इंटरफ़ेस के लिए सभी विस्तार विधियाँ होंगी, और वही विधियाँ जो IList<T>किसी अन्य फ़ाइल में हैं। एक और तरीका एक ही विधि (इसके सभी अधिभार) को एक ही आंशिक में, thisपैरामीटर के लिए सभी संभव वर्गों के साथ रखना होगा - जैसे कि सभीReverseएक फ़ाइल में कार्यान्वयन। यह निर्भर करता है कि कोड वॉल्यूम के संदर्भ में कौन सा बेहतर होगा, या आप या आपके संगठन के लिए कुछ आंतरिक सम्मेलनों से अलग हो सकते हैं।

  • मैं इसका उपयोग नहीं करता हूं, लेकिन मैंने कुछ C / C ++ लोगों को इस दृष्टिकोण को पसंद करने के लिए देखा है जिनका मैं यहां वर्णन करूंगा: केवल आंशिक तरीकों के साथ वर्ग के लिए एक आंशिक बनाएं । यह इंटरफेस को परिभाषित करने और कार्यान्वयन से विधि घोषणा को अलग करने के लिए C / C ++ तरीका जैसा दिखता है।

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


14

मैंने इसे किसी के द्वारा उल्लेखित नहीं देखा है: मैं partialअपनी फ़ाइलों में नेस्टेड कक्षाएं लगाने के लिए उपयोग करता हूं ।

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

इसका मतलब यह भी है कि एक NestedClassनेस्टेड नेस्ट के MyClassपास मेरे प्रोजेक्ट्स में खुद की फाइल होगी MyClass.NestedClass.cs:।

partial class MyClass
{
    private class NestedClass
    {
        // ...
    }
}

1
मुझे आश्चर्य है कि कोई इस जवाब को क्यों नहीं ठुकराएगा। उल्लिखित प्रथा न तो एक प्रतिमान है, और न ही इससे मुझे कोई समस्या होती है।
Ivaylo Slavov

1
यह वर्ग फ़ाइलों को छोटे रखने की समस्या को भी संबोधित करता है (कोड की पंक्तियों के संदर्भ में) जबकि अभी भी कोड के उचित इनकैप्सुलेशन की अनुमति देता है जो एक आंतरिक वर्ग में है।
Redcalx

10

उत्पन्न कोड का उपयोग करने के अपवाद के साथ, मैंने केवल उन्हें कभी भी देव वस्तुओं के लिए उपयोग करने के प्रयास में देखा है । एक नया कोडबेस समझने या कई स्रोत फ़ाइलों के माध्यम से नेविगेट करने की कोशिश करना, जो कि एक ही वस्तु है, सोओ परेशान है।

इसलिए जब आप पूछते हैं Why use partial classes?मैं जवाब देता हूं: जब तक आप उत्पन्न कोड का उपयोग नहीं कर रहे हैं, तब तक नहीं।


+1। यह पहली बार है जब मैं इस प्रकार की वस्तुओं को एक नाम (देव वस्तु) कहा जा रहा हूं और यह आधिकारिक भी है। कुछ नया सीखने में कभी देर नहीं होती।
Ivaylo Slavov

6

कोड संगठन ही एकमात्र कारण है, लेकिन यह पहले से कहीं अधिक गहरा लगता है। यदि आपके पास आंशिक कक्षाएं हैं, जहां भाग उत्पन्न होते हैं, तो आप आसानी से कर सकते हैं:

  • आपके द्वारा लिखी जाने वाली कक्षाओं में मैनुअल परिवर्तनों का पता लगाने के बिना कोड को पुनर्जन्म करें (ताकि आप उन हिस्सों को अधिलेखित न करें)।
  • परीक्षण कवरेज, स्रोत नियंत्रण, मैट्रिक्स आदि से उत्पन्न आंशिक कक्षाओं को छोड़ दें।
  • आपको इसके बिना अपनी विरासत की रणनीति को आधार बनाने के लिए उत्पन्न कोड का उपयोग करें (आप अभी भी अन्य वर्गों से विरासत में प्राप्त कर सकते हैं)।

1

कुछ स्थान ऐसे भी हैं जहाँ उत्पन्न / निहित वर्गों को आंशिक घोषित किया जाता है, इसलिए यदि देवता को उन्हें विस्तारित करने की आवश्यकता होती है, तो उन्हें पूरे स्थान पर विरासत और ओवरराइडिंग के बारे में गड़बड़ किए बिना पूर्ण पहुंच होती है। यदि आप कुछ उदाहरणों को पकड़ने की कोशिश करना चाहते हैं तो IIS के तहत पहली बार वेबफॉर्म साइट चलाने के बाद asp.net अस्थायी क्षेत्र में उत्पन्न वर्गों को देखें।


1

मैं उनके लिए एक गंदे उपयोग के बारे में सोच सकता हूं।

मान लें कि आपके पास कुछ वर्ग हैं जिन्हें सामान्य कार्यक्षमता की आवश्यकता है, लेकिन आप उस कार्यक्षमता को उनके ऊपर विरासत श्रृंखला में इंजेक्ट नहीं करना चाहते हैं। या, आपके पास उन वर्गों का एक समूह है जो एक सामान्य सहायक वर्ग का उपयोग करते हैं।

मूल रूप से आप मल्टीपल इनहेरिटेंस करना चाहते हैं लेकिन C # नो लाइक। तो जो आप करते हैं वह आंशिक रूप से बनाने के लिए उपयोग करता है जो कि अनिवार्य रूप से सी / सी ++ में एक # जीत है;

सभी कार्यक्षमता को एक वर्ग में रखें, या सहायक वर्ग का उपयोग करें। फिर सहायक एक्स बार की प्रतिलिपि बनाएँ और इसे आंशिक वर्ग ए, बी, सी नाम दें। और अपने ए, बी, सी कक्षाओं पर आंशिक रूप से रखें।

अस्वीकरण: हाँ, यह बुराई है। कभी मत करो - खासकर अगर यह अन्य लोगों को आप पर पागल बना देगा।


Mixins। मैन्युअल नकल से बचने के लिए इसे T4 के साथ जोड़ा जा सकता है ...
पीटर टेलर

जैसा कि कहा गया है, यह बारीकी से मिक्सिन जैसा दिखता है। हालाँकि, आप "लक्षण" के रूप में ज्ञात एक अवधारणा के निकट आ रहे हैं और वे सुरक्षित रूप से संभाल लेंगे कि आप क्या हासिल करने की कोशिश कर रहे हैं। मेरे पास publius-ovidius.livejournal.com/314737.html पर एक भाषा-अज्ञेय वर्णन है मैंने C # के लिए एक साफ कार्यान्वयन के लिए देखा है, लेकिन एक नहीं देखा है।
डिविड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.