क्या सामान्य प्रकार से विरासत में प्राप्त करना अच्छा है?


35

क्या List<string>टाइप एनोटेशन या StringListजहां उपयोग करना बेहतर हैStringList

class StringList : List<String> { /* no further code!*/ }

मैं में भाग कई की इन में विडंबना


यदि आप सामान्य प्रकार से विरासत में नहीं आते हैं, तो वे वहां क्यों हैं?
मग

7
@ Mawg वे केवल तात्कालिकता के लिए उपलब्ध हो सकते हैं।
थियोडोरोस चट्जीगानियाकिस

3
यह कोड में देखने के लिए मेरी सबसे कम पसंदीदा चीजों में से एक है
किक डिक

4
छी। नहीं, सचमुच में। के बीच StringListऔर शब्दार्थ क्या है List<string>? कोई भी नहीं है, फिर भी आप (सामान्य "आप") कोड आधार पर एक और विवरण जोड़ने में कामयाब रहे जो केवल आपकी परियोजना के लिए अद्वितीय है और कोड का अध्ययन करने के बाद किसी और के लिए इसका मतलब नहीं है। केवल तार की सूची को जारी रखने के लिए स्ट्रिंग्स की सूची का नाम क्यों रखें? दूसरी ओर, यदि आप ऐसा करना चाहते हैं तो BagOBagels : List<string>मुझे लगता है कि इससे अधिक समझ में आता है। आप इसे IEnumerable के रूप में प्रसारित कर सकते हैं, बाहरी उपभोक्ता कार्यान्वयन के बारे में परवाह नहीं करते हैं - अच्छाई सभी 'दौर।
क्रेग 5

1
XAML में एक मुद्दा है जहां आप जेनेरिक का उपयोग नहीं कर सकते हैं और आपको सूची को पॉप्युलेट करने के लिए इस तरह का एक प्रकार बनाने की आवश्यकता है
डैनियल लिटिल

जवाबों:


27

एक और कारण है कि आप एक सामान्य प्रकार से विरासत में क्यों प्राप्त करना चाहते हैं।

Microsoft विधि हस्ताक्षर में सामान्य प्रकार के नेस्टिंग से बचने की सलाह देता है ।

यह एक अच्छा विचार है, तो अपने कुछ जेनेरिक के लिए बिजनेस-डोमेन नाम टाइप करने के लिए। ए होने के बजाय IEnumerable<IDictionary<string, MyClass>>, एक प्रकार बनाएं MyDictionary : IDictionary<string, MyClass>और फिर आपका सदस्य एक बन जाता है IEnumerable<MyDictionary>, जो बहुत अधिक पठनीय है। यह आपको कई स्थानों पर माइकोर्ड का उपयोग करने की अनुमति देता है, जिससे आपके कोड का अन्वेषण बढ़ जाता है।

यह एक बहुत बड़े लाभ की तरह नहीं लग सकता है, लेकिन वास्तविक दुनिया के व्यापार कोड में मैंने जेनेरिक को देखा है जो आपके बालों को अंत में खड़ा करेगा। जैसी बातें List<Tuple<string, Dictionary<int, List<Dictionary<string, List<double>>>>>। उस सामान्य का अर्थ किसी भी तरह से स्पष्ट नहीं है। फिर भी, यदि इसका निर्माण स्पष्ट रूप से निर्मित श्रृंखलाओं के साथ किया गया है, तो मूल डेवलपर का इरादा बहुत अधिक स्पष्ट होगा। इसके बाद भी, अगर उस सामान्य प्रकार को किसी कारण से बदलने की जरूरत है, तो उस सामान्य प्रकार के सभी उदाहरणों को ढूंढना और उनकी जगह लेना एक वास्तविक दर्द हो सकता है, जबकि इसे व्युत्पन्न वर्ग में बदलना है।

अंत में, एक और कारण है कि कोई व्यक्ति जेनेरिक से प्राप्त अपने स्वयं के प्रकार बनाने की इच्छा कर सकता है। निम्नलिखित वर्गों पर विचार करें:

public class MyClass
{
    public ICollection<MyItems> MyItems { get; private set; }
    // plumbing code here
}

public class MyOtherClass
{
    public ICollection<MyItems> MyItemCache { get; private set; }
    // plumbing code here
}

public class MyConsumerClass
{
    public MyConsumerClass(ICollection<MyItems> myItems)
    {
        // use the collection
    }
}

अब हमें कैसे पता चलेगा कि ICollection<MyItems>MyConsumerClass के लिए कंस्ट्रक्टर में किसे पास होना है? यदि हम व्युत्पन्न कक्षाएं बनाते हैं class MyItems : ICollection<MyItems>और class MyItemCache : ICollection<MyItems>, MyConsumerClass तब बेहद विशिष्ट हो सकता है, जो वास्तव में दो संग्रहों में से एक चाहता है। यह एक IoC कंटेनर के साथ बहुत अच्छी तरह से काम करता है, जो दो संग्रह को बहुत आसानी से हल कर सकता है। यह प्रोग्रामर को और अधिक सटीक बनाने की अनुमति देता है - अगर यह MyConsumerClassकिसी भी ICollection के साथ काम करने के लिए समझ में आता है , तो वे जनरेटर का निर्माण कर सकते हैं। अगर, हालांकि, यह कभी भी दो व्युत्पन्न प्रकारों में से एक का उपयोग करने के लिए व्यावसायिक अर्थ नहीं रखता है, तो डेवलपर कंस्ट्रक्टर पैरामीटर को विशिष्ट प्रकार तक सीमित कर सकता है।

सारांश में, अक्सर सामान्य प्रकार से व्युत्पन्न प्रकारों के लिए यह सार्थक है - यह अधिक स्पष्ट कोड के लिए अनुमति देता है जहां उपयुक्त और पठनीयता और बनाए रखने में मदद करता है।


12
यह एक बिल्कुल हास्यास्पद Microsoft अनुशंसा है।
थॉमस ईडिंग

7
मुझे नहीं लगता कि यह सार्वजनिक एपीआई के लिए हास्यास्पद है। नेस्टेड जेनरिक को एक नज़र में समझना मुश्किल है और अधिक सार्थक प्रकार का नाम अक्सर पठनीयता में सहायता कर सकता है।
स्टीफन

4
मुझे नहीं लगता कि यह हास्यास्पद है, और यह निजी एपीआई के लिए निश्चित रूप से ठीक है ... लेकिन सार्वजनिक एपीआई के लिए मुझे नहीं लगता कि यह एक अच्छा विचार है। यहां तक ​​कि जब आप API को सार्वजनिक उपभोग के लिए लिख रहे होते हैं, तब भी Microsoft प्रकारों को स्वीकार करने और वापस करने की सलाह देता है।
पॉल डिआवर

35

सिद्धांत रूप में जेनेरिक प्रकारों से विरासत में और कुछ और से विरासत में कोई अंतर नहीं है।

हालाँकि, पृथ्वी पर आप किसी भी वर्ग से क्यों प्राप्त करेंगे और आगे कुछ भी नहीं जोड़ेंगे?


17
मैं सहमत हूँ। कुछ भी योगदान दिए बिना, मैं "स्ट्रिंगलिस्ट" पढ़ूंगा और खुद को सोचूंगा, "यह वास्तव में क्या करता है?"
नील

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

14
-1, यह समझने के लिए नहीं कि यह एक अलग नाम चुनकर अमूर्तता पैदा करने का सिर्फ एक तरीका है - अमूर्तता पैदा करना इस वर्ग के लिए कुछ भी नहीं जोड़ने का एक बहुत अच्छा कारण हो सकता है।
डॉक ब्राउन

1
मेरे जवाब पर विचार करें, मैं उन कुछ कारणों में जाता हूं जो कोई व्यक्ति ऐसा करने का निर्णय ले सकता है।
NPSF3000

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

13

मैं C # को बहुत अच्छी तरह से नहीं जानता, लेकिन मेरा मानना ​​है कि इसे लागू करने का एकमात्र तरीका है typedef, जिसे C ++ प्रोग्रामर आमतौर पर कुछ कारणों से उपयोग करते हैं:

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

उन्होंने मूल रूप से उबाऊ, सामान्य नामों का चयन करके अंतिम लाभ को फेंक दिया, लेकिन अन्य दो कारण अभी भी खड़े हैं।


7
एह ... वे काफी समान नहीं हैं। C ++ में आपके पास शाब्दिक उपनाम है। StringList है एक List<string>- वे interchangeably उपयोग किया जा सकता है। यह महत्वपूर्ण है जब अन्य APIs (या अपने API को उजागर करते समय) के साथ काम किया जाए, क्योंकि दुनिया में बाकी सभी लोग उपयोग करते हैं List<string>
तेलस्तीन

2
मुझे पता है कि वे वास्तव में एक ही बात नहीं कर रहे हैं। जैसे ही पास उपलब्ध है। कमजोर संस्करण के लिए निश्चित रूप से कमियां हैं।
कार्ल बेवलफेल्ट

24
नहीं, using StringList = List<string>;एक टाइपसीफ का निकटतम C # समतुल्य है। इस तरह से उप-तर्क देने से तर्क के साथ किसी भी निर्माणकर्ताओं का उपयोग रोका जा सकेगा।
पीट किर्कम

4
@PeteKirkham: StringList को परिभाषित करके usingइसे स्रोत कोड फ़ाइल में प्रतिबंधित करता है जहां usingरखा गया है। इस दृष्टिकोण से, वंशानुक्रम करीब है typedef। और एक उपवर्ग का निर्माण एक को सभी निर्माणकर्ताओं को जोड़ने से रोकता नहीं है (हालांकि यह थकाऊ हो सकता है)।
डॉक ब्राउन

2
@ Random832: मुझे इसे अलग तरीके से व्यक्त करने दें: C ++ में, एक टाइप्डेफ़ का उपयोग एक स्थान पर नाम निर्दिष्ट करने के लिए किया जा सकता है , ताकि इसे "सत्य का एकल स्रोत" बनाया जा सके। C # में, usingइस उद्देश्य के लिए उपयोग नहीं किया जा सकता है, लेकिन इनहेरिटेंस कर सकते हैं। इससे पता चलता है कि मैं पीट किर्खम की उकसाने वाली टिप्पणी से असहमत हूं - मैं usingसी ++ के वास्तविक विकल्प के रूप में विचार नहीं करता typedef
डॉक ब्राउन

9

मैं कम से कम एक व्यावहारिक कारण के बारे में सोच सकता हूं।

गैर-जेनेरिक प्रकारों की घोषणा करना, जो जेनेरिक प्रकारों (यहां तक ​​कि कुछ भी जोड़ने के बिना) से विरासत में मिला है, उन प्रकारों को उन जगहों से संदर्भित करने की अनुमति देता है जहां वे अन्यथा अनुपलब्ध होंगे, या उनसे अधिक जटिल तरीके से उपलब्ध होने चाहिए।

ऐसा ही एक मामला विजुअल स्टूडियो में सेटिंग्स एडिटर के माध्यम से सेटिंग्स को जोड़ने पर है, जहां केवल गैर-जेनेरिक प्रकार ही उपलब्ध हैं। यदि आप वहां जाते हैं, तो आप देखेंगे कि सभी System.Collectionsकक्षाएं उपलब्ध हैं, लेकिन कोई भी संग्रह System.Collections.Genericलागू नहीं होता है।

एक और मामला है जब WPF में XAML के माध्यम से तत्काल प्रकार। 2009 के पूर्व स्कीमा का उपयोग करते समय XML सिंटैक्स में टाइप आर्ग्युमेंट्स पास करने के लिए कोई समर्थन नहीं है। यह इस तथ्य से भी बदतर बना है कि 2006 स्कीमा नए WPF प्रोजेक्ट्स के लिए डिफ़ॉल्ट है।


1
WCF वेब सेवा इंटरफेस में आप बेहतर दिखने वाले संग्रह प्रकार के नाम (उदाहरण के लिए। ArrayOfPerson या जो भी हो) के बजाय पर्सनॉल्यूशन प्रदान करने के लिए इस तकनीक का उपयोग कर सकते हैं
रिको

7

मुझे लगता है कि आपको कुछ इतिहास पर ध्यान देने की आवश्यकता है ।

  • C # का उपयोग बहुत अधिक समय से किया गया है, क्योंकि इसमें सामान्य प्रकार के गुण हैं।
  • मुझे उम्मीद है कि दिए गए सॉफ़्टवेयर का इतिहास में कुछ बिंदु पर अपना स्ट्रिंगरलिस्ट था।
  • यह अच्छी तरह से एक ArrayList लपेटकर लागू किया गया हो सकता है।
  • फिर किसी को कोड बेस को आगे बढ़ाने के लिए रीफैक्टरिंग करना होगा।
  • लेकिन 1001 अलग-अलग फ़ाइलों को छूने की इच्छा नहीं थी, इसलिए काम खत्म करें।

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


3
"C # का उपयोग बहुत अधिक समय से किया गया है, क्योंकि इसमें सामान्य प्रकार हैं।" वास्तव में, बिना जेनरिक के C # लगभग 4 साल (जनवरी 2002 - नवंबर 2005) में मौजूद था, जबकि जेनरिक के साथ C # अब 9 साल का हो चुका है।
स्विक


4

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

अगर संभव होता तो मैं इससे बचता।

एक टंकण के विपरीत, आप एक नया प्रकार बनाते हैं। यदि आप StringList को एक विधि के इनपुट पैरामीटर के रूप में उपयोग करते हैं, तो आपके कॉलर्स पास नहीं कर सकते List<string>

इसके अलावा, आपको उन सभी कंस्ट्रक्टरों को स्पष्ट रूप से कॉपी करने की आवश्यकता होगी, जिनका आप उपयोग करने के लिए, StringList उदाहरण में, जो आप नहीं कह सकते new StringList(new[]{"a", "b", "c"}), हालांकिList<T> ऐसे कंस्ट्रक्टर को परिभाषित करता हो।

संपादित करें:

स्वीकृत उत्तर आपके डोमेन मॉडल के अंदर व्युत्पन्न प्रकारों का उपयोग करते समय समर्थक पर केंद्रित होता है। मैं सहमत हूं कि वे इस मामले में संभावित रूप से उपयोगी हो सकते हैं, फिर भी, मैं व्यक्तिगत रूप से वहां भी उनसे बचूंगा।

लेकिन आपको (मेरी राय में) कभी भी सार्वजनिक एपीआई में इनका उपयोग नहीं करना चाहिए क्योंकि आप या तो अपने कॉलर के जीवन को कठिन बनाते हैं या बेकार प्रदर्शन करते हैं (मुझे वास्तव में सामान्य रूप से निहित रूपांतरण पसंद नहीं हैं)।


3
आप कहते हैं, " आप XAML में एक सामान्य प्रकार का संदर्भ नहीं दे सकते हैं ", लेकिन मुझे यकीन नहीं है कि आप क्या उल्लेख कर रहे हैं।
जेएएमएल

1
यह एक उदाहरण के रूप में था। हां, यह 2009 XAML स्कीमा के साथ संभव है, लेकिन AFAIK 2006 स्कीमा के साथ नहीं है, जो अभी भी वीएस डिफ़ॉल्ट है।
लुकास रिगर

1
आपका तीसरा पैराग्राफ सिर्फ आधा सच है, आप इसे वास्तव में निहित कन्वर्टर्स के साथ अनुमति दे सकते हैं;)
Knerd

1
@Knerd, सच है, लेकिन फिर आप 'अंतर्निहित' एक नई वस्तु बनाते हैं। जब तक आप बहुत अधिक काम नहीं करेंगे, यह डेटा की एक प्रति भी बनाएगा। शायद छोटी सूचियों के साथ कोई फर्क नहीं पड़ता, लेकिन मज़े करो, अगर कोई व्यक्ति कुछ हजार तत्वों के साथ एक सूची पास करता है =)
लुकास रीगर

@LukasRieger आप सही हैं: पीआई केवल यह बताना चाहता था कि: पी
केर्नड

2

यह क्या है इसके लिए, यहाँ एक उदाहरण दिया गया है कि कैसे जेनेरिक क्लास से विरासत में माइक्रोसॉफ्ट के रोसलिन कंपाइलर का उपयोग किया जाता है, और क्लास का नाम बदले बिना भी। (मैं इससे इतना भड़क गया था कि मैं अपनी खोज में यहाँ समाप्त हो गया, यह देखने के लिए कि क्या यह वास्तव में संभव था।)

प्रोजेक्ट कोडएनालिसिस में आप यह परिभाषा पा सकते हैं:

/// <summary>
/// Common base class for C# and VB PE module builder.
/// </summary>
internal abstract class PEModuleBuilder<TCompilation, TSourceModuleSymbol, TAssemblySymbol, TTypeSymbol, TNamedTypeSymbol, TMethodSymbol, TSyntaxNode, TEmbeddedTypesManager, TModuleCompilationState> : CommonPEModuleBuilder, ITokenDeferral
    where TCompilation : Compilation
    where TSourceModuleSymbol : class, IModuleSymbol
    where TAssemblySymbol : class, IAssemblySymbol
    where TTypeSymbol : class
    where TNamedTypeSymbol : class, TTypeSymbol, Cci.INamespaceTypeDefinition
    where TMethodSymbol : class, Cci.IMethodDefinition
    where TSyntaxNode : SyntaxNode
    where TEmbeddedTypesManager : CommonEmbeddedTypesManager
    where TModuleCompilationState : ModuleCompilationState<TNamedTypeSymbol, TMethodSymbol>
{
  ...
}

फिर प्रोजेक्ट CSharpCodeanalysis में यह परिभाषा है:

internal abstract class PEModuleBuilder : PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, NoPia.EmbeddedTypesManager, ModuleCompilationState>
{
  ...
}

यह गैर-जेनेरिक PEModuleBuilder वर्ग CSharpCodeanalysis परियोजना में बड़े पैमाने पर उपयोग किया जाता है, और उस परियोजना के कई वर्ग इसे प्रत्यक्ष या अप्रत्यक्ष रूप से प्राप्त करते हैं।

और फिर परियोजना में BasicCodeanalysis वहाँ इस परिभाषा है:

Partial Friend MustInherit Class PEModuleBuilder
    Inherits PEModuleBuilder(Of VisualBasicCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, NoPia.EmbeddedTypesManager, ModuleCompilationState)

चूँकि हम (उम्मीद) यह मान सकते हैं कि रोज़लिन को C # के व्यापक ज्ञान वाले लोगों द्वारा लिखा गया था और इसका उपयोग कैसे किया जाना चाहिए, मैं सोच रहा हूँ कि यह तकनीक की सिफारिश है।


हाँ। और यह भी कि वे घोषित किए जाने पर सीधे क्लॉज को परिष्कृत करने के लिए उपयोग किया जा सकता है।
प्रहरी

1

तीन संभावित कारण हैं कि कोई मेरे सिर के ऊपर से ऐसा करने की कोशिश करेगा:

1) घोषणाओं को आसान बनाने के लिए:

यकीन है StringListऔर ListStringएक ही लंबाई के बारे में हैं, लेकिन कल्पना कीजिए कि आप UserCollectionवास्तव में Dictionary<Tuple<string,Type>, IUserData<Dictionary,MySerializer>>या किसी अन्य बड़े सामान्य उदाहरण के साथ काम कर रहे हैं ।

2) एओटी की मदद करने के लिए:

कभी-कभी आपको समय संकलन में केवल समय संकलन का उपयोग करने की आवश्यकता होती है - जैसे कि iOS के लिए विकसित करना। कभी-कभी एओटी कंपाइलर को समय से पहले सभी सामान्य प्रकारों का पता लगाने में कठिनाई होती है, और यह संकेत देने का प्रयास हो सकता है।

3) कार्यक्षमता जोड़ने या निर्भरता को दूर करने के लिए:

हो सकता है कि उनके पास विशिष्ट कार्यक्षमता हो, जिसे वे लागू करना चाहते हैं StringList(एक एक्सटेंशन विधि में छिपाया जा सकता है, अभी तक जोड़ा नहीं गया है, या ऐतिहासिक) जिसे वे या तो List<string>इसे से विरासत में मिलाए बिना नहीं जोड़ सकते हैं , या कि वे प्रदूषित नहीं करना चाहते हैंList<string> जिनके साथ ।

वैकल्पिक रूप से वे StringListट्रैक के कार्यान्वयन को बदलने की इच्छा कर सकते हैं , इसलिए अभी के लिए एक मार्कर के रूप में वर्ग का उपयोग किया है (आमतौर पर आप इसके लिए इंटरफेस का उपयोग करेंगे / जैसे IList)।


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

इन उदाहरणों से पता चलता है कि इस तरह की घोषणा लिखने के वैध कारण हो सकते हैं - भले ही यह बहुत आम न हो। जैसा कि कुछ के साथ कई विकल्पों पर विचार करें और उस समय चुनें जो आपके लिए सबसे अच्छा है।


यदि आपके पास स्रोत कोड पर एक नज़र है तो ऐसा प्रतीत होता है विकल्प 3 कारण है - वे इस तकनीक का उपयोग कार्यक्षमता / विशेषज्ञ संग्रह को जोड़ने में मदद करने के लिए करते हैं:

public class StringList : List<string> {
    public StringList() { }
    public StringList(params string[] args) {
      AddRange(args);
    }
    public override string ToString() {
      return ToString(" ");
    }
    public string ToString(string separator) {
      return Strings.JoinStrings(separator, this);
    }
    //Used in sorting suffixes and prefixes; longer strings must come first in sort order
    public static int LongerFirst(string x, string y) {
      try {//in case any of them is null
        if (x.Length > y.Length) return -1;
      } catch { }
      if (x == y) return 0;
      return 1; 
    }

1
कभी-कभी घोषणाओं को सरल बनाने की खोज (या जो कुछ भी सरल करता है) कम जटिलता के बजाय बढ़ी हुई जटिलता में परिणाम कर सकता है। हर कोई जो भाषा को मामूली रूप से जानता है वह अच्छी तरह जानता है कि क्या List<T>है, लेकिन उन्हें StringListवास्तव में यह समझने के लिए संदर्भ में निरीक्षण करना होगा कि यह क्या है। वास्तव में, यह सिर्फ List<string>एक अलग नाम से जा रहा है। वहाँ वास्तव में इस तरह के एक साधारण मामले में ऐसा करने के लिए कोई अर्थ लाभ नहीं लगता है। आप वास्तव में सिर्फ एक प्रसिद्ध प्रकार की जगह ले रहे हैं एक ही प्रकार से एक अलग नाम से जा रहा है।
क्रेग

@ क्रेग मैं सहमत हूं, जैसा कि यूजेस के मेरे स्पष्टीकरण (लंबी घोषणाओं) और अन्य संभावित कारणों से उल्लेखित है।
NPSF3000

-1

मैं कहूंगा कि यह अच्छा अभ्यास नहीं है।

List<string>संचार "तार की एक सामान्य सूची"। स्पष्ट रूप से List<string> विस्तार विधियाँ लागू होती हैं। समझने के लिए कम जटिलता की आवश्यकता होती है; केवल सूची की आवश्यकता है।

StringList"एक अलग वर्ग की आवश्यकता" का संचार करता है। हो सकता है कि List<string> विस्तार विधियाँ लागू हों (इसके लिए वास्तविक प्रकार का कार्यान्वयन देखें)। कोड को समझने के लिए अधिक जटिलता की आवश्यकता है; सूची और व्युत्पन्न वर्ग कार्यान्वयन ज्ञान की आवश्यकता है।


4
एक्सटेंशन के तरीके वैसे भी लागू होते हैं।
थियोडोरोस चट्जीगानियाकिन्स

2
अनिच्छित कार्य होना। लेकिन आप नहीं जानते कि जब तक आप StringList का निरीक्षण नहीं करते हैं और देखते हैं कि यह व्युत्पन्न है List<string>
रुदजाह

@ TheodorosChatzigiannakis मुझे आश्चर्य है कि अगर Ruudjah "उसके द्वारा लागू किए जाने वाले तरीकों" का मतलब क्या है, इस पर विस्तार से बता सकता है। विस्तार विधियां किसी भी वर्ग के साथ होने की संभावना है । निश्चित रूप से, .NET फ्रेमवर्क लाइब्रेरी जहाजों में बहुत सारे विस्तार के तरीके हैं, जिन्हें LINQ कहा जाता है, जो सामान्य संग्रह कक्षाओं पर लागू होते हैं, लेकिन इसका मतलब यह नहीं है कि एक्सटेंशन विधियां किसी अन्य वर्गों पर लागू नहीं होती हैं? शायद रुदजाह एक ऐसी बात बना रहा है जो पहली नज़र में स्पष्ट नहीं है? ;-)
क्रेग

"विस्तार विधियाँ लागू नहीं होती हैं।" आप इसे कहाँ पढ़ते हैं? मैं कह रहा हूं "विस्तार विधियां लागू हो सकती हैं।
रुदजाह

1
प्रकार कार्यान्वयन आपको यह नहीं बताएगा कि एक्सटेंशन विधियां लागू होती हैं या नहीं, हालांकि, सही है? बस तथ्य यह है कि यह एक वर्ग के साधन विस्तार के तरीकों है है लागू होते हैं। आपके प्रकार का कोई भी उपभोक्ता आपके कोड के स्वतंत्र रूप से विस्तार के तरीके बना सकता है। मुझे लगता है कि मैं क्या कर रहा हूँ या पूछ रहा हूँ। क्या आप सिर्फ LINQ के बारे में बात कर रहे हैं? LINQ एक्सटेंशन विधियों का उपयोग करके कार्यान्वित किया जाता है । लेकिन एक विशेष प्रकार के लिए LINQ- विशिष्ट एक्सटेंशन विधियों की अनुपस्थिति का मतलब यह नहीं है कि उस प्रकार के एक्सटेंशन तरीके मौजूद नहीं हैं, या नहीं। वे किसी भी समय किसी के भी द्वारा बनाए जा सकते थे।
क्रेग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.