क्या है संशोधन?


163

मुझे पता है कि जावा उन्मूलन के साथ पैरामीट्रिक बहुरूपता (जेनरिक) को लागू करता है। मैं समझता हूं कि क्षरण क्या है।

मुझे पता है कि सी # संशोधन के साथ पैरामीट्रिक बहुरूपता को लागू करता है। मुझे पता है कि आप लिख सकते हैं

public void dosomething(List<String> input) {}
public void dosomething(List<Int> input) {}

या कि आप रनटाइम पर जान सकते हैं कि कुछ पैरामीटर किए गए प्रकार का प्रकार क्या है, लेकिन मुझे समझ नहीं आता कि यह क्या है

  • एक रिवाइज्ड टाइप क्या है?
  • एक पुनरीक्षित मूल्य क्या है?
  • जब एक प्रकार / मूल्य का पुनरीक्षण किया जाता है तो क्या होता है?

यह कोई जवाब नहीं है, लेकिन किसी की मदद कर सकता है: beust.com/weblog/2011/07/29/erasure-vs-reification
heringer

@ हेरिंग जो प्रश्न "क्या इरेज़र है" का अच्छी तरह से उत्तर देता है, और मूल रूप से "क्या नहीं है" के साथ "क्या है" का उत्तर "लगता है" - एक सामान्य विषय जो मैंने शुरू में यहां पोस्ट करने से पहले एक उत्तर की खोज में पाया था।
Martijn

5
... और वहाँ मुझे यह सोच कर फिर से था ification एक परिवर्तित करने की प्रक्रिया है switchएक करने के लिए निर्माण वापस if/ else, जब यह पहले से एक से परिवर्तित कर दिया गया था if/ elseएक के लिए switch...
डिजिटल ट्रामा

8
Res , reis बात के लिए लैटिन है , इसलिए reification का शाब्दिक अर्थ है । मेरे पास शब्द के C # के उपयोग के रूप में योगदान करने के लिए कुछ भी उपयोगी नहीं है, लेकिन इस तथ्य का कि वे इसका उपयोग करते हैं, मुझे मुस्कुराता है।
केरान

जवाबों:


209

संशोधन एक अमूर्त चीज लेने और एक ठोस चीज बनाने की प्रक्रिया है।

C # जेनरिक में टर्म रिफ़ॉर्मेशन उस प्रक्रिया को संदर्भित करता है जिसके द्वारा एक जेनेरिक प्रकार की परिभाषा और एक या अधिक जेनेरिक प्रकार के तर्क (अमूर्त चीज़) को एक नया जेनेरिक प्रकार (ठोस चीज़) बनाने के लिए संयोजित किया जाता है ।

वाक्यांश के लिए इसे दूसरे तरीके से, यह की परिभाषा लेने की प्रक्रिया है List<T>और intऔर एक ठोस उत्पादन List<int>प्रकार।

इसे और समझने के लिए, निम्नलिखित तरीकों की तुलना करें:

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

    1. इस कार्यान्वयन तकनीक के साइड इफेक्ट के रूप में, केवल सामान्य प्रकार के तर्क जो मूल रूप से अनुमत हैं, वे प्रकार हैं जो अपने कंक्रीट प्रकार के बाइनरी कोड को साझा कर सकते हैं; जिसका अर्थ है उन प्रकार जिनके भंडारण स्थानों में विनिमेय प्रतिनिधित्व है; जिसका अर्थ है संदर्भ प्रकार। सामान्य प्रकार के तर्कों के रूप में मूल्य प्रकारों का उपयोग करके उन्हें बॉक्सिंग की आवश्यकता होती है (उन्हें एक साधारण संदर्भ प्रकार के आवरण में रखकर)।
    2. इस तरह से जेनरिक को लागू करने के लिए किसी भी कोड की नकल नहीं की जाती है।
    3. टाइप जानकारी जो रनटाइम पर उपलब्ध हो सकती थी (प्रतिबिंब का उपयोग करके) खो गई है। यह बदले में, इसका मतलब है कि एक सामान्य प्रकार ( किसी विशेष सामान्य तर्क संयोजन के लिए विशेष स्रोत कोड का उपयोग करने की क्षमता) का विशेषज्ञता बहुत प्रतिबंधित है।
    4. इस तंत्र को रनटाइम वातावरण से समर्थन की आवश्यकता नहीं है।
    5. टाइप जानकारी को बनाए रखने के लिए कुछ वर्कअराउंड हैं जो एक जावा प्रोग्राम या एक जेवीएम-आधारित भाषा का उपयोग कर सकते हैं।
  • C # जेनरिक में, रनटाइम पर जेनेरिक प्रकार की परिभाषा को स्मृति में बनाए रखा जाता है। जब भी एक नए ठोस प्रकार की आवश्यकता होती है, तो रनटाइम वातावरण सामान्य प्रकार की परिभाषा और प्रकार के तर्कों को जोड़ती है और नए प्रकार (संशोधन) का निर्माण करता है। इसलिए हमें रनटाइम पर टाइप तर्कों के प्रत्येक संयोजन के लिए एक नया प्रकार मिलता है

    1. यह कार्यान्वयन तकनीक किसी भी प्रकार के तर्क संयोजन को तत्काल करने की अनुमति देती है। सामान्य प्रकार के तर्कों के रूप में मूल्य प्रकारों का उपयोग करने से मुक्केबाजी का कारण नहीं बनता है, क्योंकि इन प्रकारों का अपना कार्यान्वयन होता है। ( बॉक्सिंग अभी भी C # में मौजूद है , लेकिन यह अन्य स्थितियों में होता है, यह नहीं।)
    2. कोड दोहराव एक मुद्दा हो सकता है - लेकिन व्यवहार में यह नहीं है, क्योंकि पर्याप्त रूप से स्मार्ट कार्यान्वयन ( इसमें Microsoft .NET और मोनो शामिल हैं ) कुछ तात्कालिकता के लिए कोड साझा कर सकते हैं।
    3. प्रकार की जानकारी को बनाए रखा जाता है, जो प्रतिबिंब का उपयोग करके प्रकार के तर्कों की जांच करके, एक हद तक विशेषज्ञता की अनुमति देता है। हालांकि, विशेषज्ञता की डिग्री सीमित है, इस तथ्य के परिणामस्वरूप कि किसी भी संशोधन के होने से पहले एक सामान्य प्रकार की परिभाषा संकलित की जाती है (यह प्रकार मापदंडों पर बाधाओं के खिलाफ परिभाषा को संकलित करके किया जाता है - इस प्रकार, संकलक को सक्षम होना पड़ता है "समझ" विशिष्ट प्रकार के तर्कों के अभाव में भी परिभाषा )।
    4. यह कार्यान्वयन तकनीक रनटाइम सपोर्ट और जेआईटी-संकलन (जो अक्सर आप सुनते हैं कि सी # जेनरिक की आईओएस जैसे प्लेटफॉर्म पर कुछ सीमाएँ हैं , जहां डायनेमिक कोड जेनरेशन प्रतिबंधित है) पर बहुत अधिक निर्भर करता है ।
    5. C # जेनरिक के संदर्भ में, रनटाइम पर्यावरण द्वारा आपके लिए पुनरीक्षण किया जाता है। हालाँकि, यदि आप जेनेरिक प्रकार की परिभाषा और एक ठोस जेनेरिक प्रकार के बीच अंतर को अधिक सहजता से समझना चाहते हैं, तो आप हमेशा System.Typeकक्षा का उपयोग करते हुए (भले ही सामान्य जेनेरिक प्रकार के तर्क संयोजन का उपयोग कर रहे हों, आप तुरंत पुनर्मुद्रण कर सकते हैं ' टी सीधे अपने स्रोत कोड में दिखाई देते हैं)।
  • C ++ टेम्प्लेट में, संकलित समय में टेम्प्लेट की परिभाषा को मेमोरी में बनाए रखा जाता है। जब भी स्रोत कोड में टेम्पलेट प्रकार की एक नई तात्कालिकता की आवश्यकता होती है, तो कंपाइलर टेम्पलेट परिभाषा और टेम्पलेट तर्क को जोड़ती है और नया प्रकार बनाता है। इसलिए हम संकलन समय पर , टेम्पलेट तर्कों के प्रत्येक संयोजन के लिए एक अद्वितीय प्रकार प्राप्त करते हैं ।

    1. यह कार्यान्वयन तकनीक किसी भी प्रकार के तर्क संयोजन को तत्काल करने की अनुमति देती है।
    2. यह बाइनरी कोड को डुप्लिकेट करने के लिए जाना जाता है, लेकिन एक पर्याप्त स्मार्ट टूल-चेन अभी भी इसका पता लगा सकता है और कुछ इंस्टेंटिएशन के लिए कोड साझा कर सकता है।
    3. टेम्पलेट की परिभाषा स्वयं "संकलित" नहीं है - केवल इसकी ठोस तात्कालिकता वास्तव में संकलित है । यह संकलक पर कम बाधाओं को रखता है और टेम्पलेट विशेषज्ञता के अधिक से अधिक डिग्री की अनुमति देता है ।
    4. चूँकि टेम्पलेट तात्कालिकता संकलन समय पर की जाती है, यहाँ कोई रनटाइम समर्थन की आवश्यकता नहीं है।
    5. इस प्रक्रिया को हाल ही में विशेष रूप से रस्ट समुदाय में मोनोमोर्फिफ़ेशन के रूप में जाना जाता है । इस शब्द का उपयोग पैरामीट्रिक बहुरूपता के विपरीत किया जाता है , जो उस अवधारणा का नाम है, जो जेनेरिक से आती है।

7
C ++ टेम्प्लेट के साथ महान तुलना ... वे C # के जावा और जावा के जेनेरिक के बीच कहीं गिरते हुए प्रतीत होते हैं। आपके पास C # जैसे विभिन्न विशिष्ट जेनेरिक प्रकारों को संभालने के लिए अलग कोड और संरचना है, लेकिन यह सभी जावा की तरह संकलन-समय में किया गया है।
लुआं

3
इसके अलावा, C ++ में यह टेम्पलेट विशेषज्ञता को पेश करने में सक्षम बनाता है, जहां प्रत्येक (या सिर्फ कुछ) ठोस प्रकार के अलग-अलग कार्यान्वयन हो सकते हैं। स्पष्ट रूप से जावा में संभव नहीं है, लेकिन न तो सी # में।
quetzalcoatl 13

@quetzalcoatl हालांकि इसका उपयोग करने का एक कारण सूचक प्रकारों के साथ उत्पादित कोड की मात्रा को कम करना है, और सी # पर्दे के पीछे संदर्भ प्रकारों के साथ तुलनीय कुछ करता है। फिर भी, इसका उपयोग करने का केवल एक कारण है, और निश्चित रूप से ऐसे समय हैं जब टेम्पलेट विशेषज्ञता अच्छी होगी।
जॉन हन्ना

जावा के लिए, आप यह जोड़ना चाह सकते हैं कि जब प्रकार की जानकारी मिट जाती है, तो संकलक द्वारा कलाकारों को जोड़ दिया जाता है, जिससे प्री-जेनेरिक बायटेकोड से बायटेकोड अप्रभेद्य बन जाता है।
रस्टी कोर

27

आम तौर पर संशोधन का अर्थ है (कंप्यूटर विज्ञान के बाहर) "कुछ वास्तविक बनाने के लिए"।

यदि हम भाषा में ही इसके बारे में जानकारी तक पहुँच सकते हैं, तो प्रोग्रामिंग में, कुछ का पुनरावलोकन किया जाता है।

कुछ सी # के दो पूरी तरह से गैर-जेनरिक-संबंधित उदाहरणों के लिए सी # करता है और पुन: लागू नहीं होता है, चलो तरीकों और मेमोरी एक्सेस का उपयोग करें।

OO भाषाओं में आमतौर पर विधियाँ होती हैं , (और कई में ऐसे कार्य नहीं होते हैं जो एक वर्ग के लिए बाध्य नहीं होते हैं)। जैसे कि आप इस तरह की भाषा में एक विधि को परिभाषित कर सकते हैं, इसे कॉल कर सकते हैं, शायद इसे ओवरराइड कर सकते हैं, और इसी तरह। ऐसी सभी भाषाएं आपको वास्तव में किसी प्रोग्राम के डेटा के रूप में विधि से निपटने की अनुमति नहीं देती हैं। C # (और वास्तव में, .NET # C के बजाय) आपको MethodInfoविधियों का प्रतिनिधित्व करने वाली वस्तुओं का उपयोग करने देता है, इसलिए C # विधियों में पुन: उपयोग किया जाता है। C # में विधियाँ "प्रथम श्रेणी की वस्तुएँ" हैं।

सभी व्यावहारिक भाषाओं में कंप्यूटर की मेमोरी तक पहुंचने के कुछ साधन हैं। C जैसी निम्न-स्तरीय भाषा में हम कंप्यूटर द्वारा उपयोग किए जाने वाले संख्यात्मक पते के बीच सीधे मैपिंग कर सकते हैं, इसलिए यह पसंद int* ptr = (int*) 0xA000000; *ptr = 42;उचित है (जब तक कि हमें इस बात पर संदेह है कि मेमोरी एड्रेस एक्सेस करने का यह एक अच्छा कारण है, 0xA000000' टी कुछ ऊपर उड़ा)। C # में यह उचित नहीं है (हम इसे केवल .NET में लागू करने के लिए बाध्य कर सकते हैं, लेकिन .NET मेमोरी प्रबंधन के साथ चीजों को इधर-उधर करना उपयोगी होने की संभावना नहीं है)। C # में मेमोरी पतों की पुष्टि नहीं है।

तो, जैसा कि परिष्कृत का अर्थ है "बनाया गया असली" एक "संशोधित प्रकार" एक प्रकार है जिसे हम भाषा में "बात कर सकते हैं" के बारे में पूछते हैं।

जेनरिक में इसका मतलब दो चीजें हैं।

एक यह है कि List<string>बस के रूप में stringया intकर रहे हैं एक प्रकार है । हम उस प्रकार की तुलना कर सकते हैं, उसका नाम प्राप्त कर सकते हैं, और उसके बारे में पूछताछ कर सकते हैं:

Console.WriteLine(typeof(List<string>).FullName); // System.Collections.Generic.List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
Console.WriteLine(typeof(List<string>) == (42).GetType()); // False
Console.WriteLine(typeof(List<string>) == Enumerable.Range(0, 1).Select(i => i.ToString()).ToList().GetType()); // True
Console.WriteLine(typeof(List<string>).GenericTypeArguments[0] == typeof(string)); // True

इसका एक परिणाम यह है कि हम एक सामान्य विधि के बारे में "बात कर सकते हैं" (या एक सामान्य वर्ग की विधि) मापदंडों के प्रकार स्वयं विधि के भीतर हैं:

public static void DescribeType<T>(T element)
{
  Console.WriteLine(typeof(T).FullName);
}
public static void Main()
{
  DescribeType(42);               // System.Int32
  DescribeType(42L);              // System.Int64
  DescribeType(DateTime.UtcNow);  // System.DateTime
}

एक नियम के रूप में, यह बहुत अधिक करना "बदबूदार" है, लेकिन इसके कई उपयोगी मामले हैं। उदाहरण के लिए, देखें:

public static TSource Min<TSource>(this IEnumerable<TSource> source)
{
  if (source == null) throw Error.ArgumentNull("source");
  Comparer<TSource> comparer = Comparer<TSource>.Default;
  TSource value = default(TSource);
  if (value == null)
  {
    using (IEnumerator<TSource> e = source.GetEnumerator())
    {
      do
      {
        if (!e.MoveNext()) return value;
        value = e.Current;
      } while (value == null);
      while (e.MoveNext())
      {
        TSource x = e.Current;
        if (x != null && comparer.Compare(x, value) < 0) value = x;
      }
    }
  }
  else
  {
    using (IEnumerator<TSource> e = source.GetEnumerator())
    {
      if (!e.MoveNext()) throw Error.NoElements();
      value = e.Current;
      while (e.MoveNext())
      {
        TSource x = e.Current;
        if (comparer.Compare(x, value) < 0) value = x;
      }
    }
  }
  return value;
}

यह TSourceविभिन्न प्रकार के व्यवहारों के लिए और विभिन्न प्रकारों के बीच बहुत सारी तुलनाएं नहीं करता है (आमतौर पर एक संकेत है कि आपको जेनरिक का उपयोग बिल्कुल नहीं करना चाहिए) लेकिन यह उन प्रकारों के लिए एक कोड पथ के बीच विभाजन करता है जो हो सकते हैं null( nullयदि लौटना चाहिए कोई तत्व नहीं मिला, और यदि किसी तत्व की तुलना में न्यूनतम है तो उसे खोजने के लिए तुलना नहीं करनी चाहिए null) और प्रकारों के लिए कोड पथ जो नहीं हो सकता है null(यदि कोई तत्व नहीं मिला तो फेंक देना चाहिए, और nullतत्वों की संभावना के बारे में चिंता करने की ज़रूरत नहीं है )।

क्योंकि TSourceविधि के भीतर "वास्तविक" है, यह तुलना रनटाइम या जटिंग टाइम पर की जा सकती है (आम तौर पर जटिंग टाइम, निश्चित रूप से उपरोक्त मामला जटिंग टाइम पर ऐसा करेगा और नहीं लिए गए पथ के लिए मशीन कोड का उत्पादन करेगा) और हमारे पास एक है प्रत्येक मामले के लिए विधि का अलग "वास्तविक" संस्करण। (हालांकि एक अनुकूलन के रूप में, मशीन कोड अलग-अलग संदर्भ-प्रकार के मापदंडों के लिए अलग-अलग तरीकों के लिए साझा किया जाता है, क्योंकि यह इसे प्रभावित किए बिना हो सकता है, और इसलिए हम मशीन कोड की मात्रा को कम कर सकते हैं)।

(यह सामान्य सी # में सामान्य प्रकार के reification के बारे में बात करने के लिए जब तक आप भी जावा के साथ सौदा है, क्योंकि सी # में हम सिर्फ प्रदान करने के लिए इस reification ले नहीं है, सभी प्रकार के reified कर रहे हैं जावा, गैर सामान्य प्रकार के रूप में भेजा जाता। Reified क्योंकि कि उनके और सामान्य प्रकार के बीच एक अंतर है)।


आपको नहीं लगता कि ऐसा करने में सक्षम होना क्या Minउपयोगी है? अन्यथा इसके प्रलेखित व्यवहार को पूरा करना बहुत कठिन है।
जॉन हैना

मैं बग को (अन) प्रलेखित व्यवहार और निहितार्थ मानता हूं कि यह व्यवहार उपयोगी है (एक तरफ के रूप में, इसका व्यवहार Enumerable.Min<TSource>अलग है कि यह एक खाली संग्रह पर गैर-संदर्भ प्रकारों के लिए नहीं फेंकता है, लेकिन डिफ़ॉल्ट रूप से लौटता है (TSource), और केवल "सामान्य अनुक्रम में न्यूनतम मान लौटाता है" के रूप में प्रलेखित किया गया है। मैं तर्क दूंगा कि दोनों को एक खाली संग्रह पर फेंकना चाहिए, या यह कि "शून्य" तत्व को आधार रेखा के रूप में पारित किया जाना चाहिए, और तुलनित्र / तुलना समारोह हमेशा पास होना चाहिए)
Martijn

1
यह वर्तमान मिन की तुलना में बहुत कम उपयोगी होगा, जो अशक्त प्रकारों पर असंभव के प्रयास के बिना अशक्त प्रकारों पर सामान्य db व्यवहार से मेल खाता है। (आधारभूत विचार असंभव नहीं है, लेकिन बहुत उपयोगी नहीं है जब तक कि कोई मूल्य नहीं हो सकता है जिसे आप जान सकते हैं कि स्रोत में कभी नहीं होगा)।
जॉन हैना

1
इसके लिए थिंगिफिकेशन एक बेहतर नाम होता। :)
tchrist

@ टिश्री एक चीज असत्य हो सकती है।
जॉन हैना

15

जैसा कि पहले से ही उल्लेख किया गया है , "संशोधन" महत्वपूर्ण अंतर नहीं है।

जावा में, जेनरिक मूल रूप से संकलन-समय के समर्थन में सुधार करने के लिए हैं - यह आपको अपने कोड में दृढ़ता से टाइप किए गए संग्रह का उपयोग करने की अनुमति देता है, और आपके लिए टाइप सुरक्षा की व्यवस्था की जाती है। हालांकि, यह केवल संकलन-समय पर मौजूद है - संकलित बायटेकोड में अब जेनरिक की कोई धारणा नहीं है; सभी सामान्य प्रकार "ठोस" प्रकारों में परिवर्तित हो जाते हैं ( objectयदि सामान्य प्रकार अनबाउंड है तो) का उपयोग करके , प्रकार के रूपांतरण और प्रकार की जाँच को आवश्यकतानुसार जोड़ा जा सकता है।

.NET में, जेनेरिक CLR की एक अभिन्न विशेषता है। जब आप एक सामान्य प्रकार संकलित करते हैं, तो यह उत्पन्न IL में सामान्य रहता है। यह सिर्फ जावा में गैर-जेनेरिक कोड में तब्दील नहीं हुआ है।

यह इस बात पर कई प्रभाव डालता है कि जेनेरिक व्यवहार में कैसे काम करते हैं। उदाहरण के लिए:

  • जावा को SomeType<?>आपको दिए गए सामान्य प्रकार के किसी भी ठोस कार्यान्वयन को पारित करने की अनुमति देनी होगी। C # ऐसा नहीं कर सकता - प्रत्येक विशिष्ट ( reified ) सामान्य प्रकार का अपना प्रकार है।
  • जावा में अनबाउंड जेनेरिक प्रकारों का मतलब है कि उनका मूल्य ए के रूप में संग्रहीत है object। ऐसे जेनेरिक में मूल्य प्रकारों का उपयोग करते समय इसका प्रदर्शन प्रभाव पड़ सकता है। C # में, जब आप जेनेरिक प्रकार में एक मान प्रकार का उपयोग करते हैं, तो यह एक मूल्य प्रकार रहता है।

नमूना देने के लिए, मान लें कि आपके पास Listएक सामान्य तर्क के साथ एक सामान्य प्रकार है। जावा में, List<String>और List<Int>रनटाइम के दौरान ठीक उसी प्रकार का अंत होगा - सामान्य प्रकार केवल संकलन-समय कोड के लिए वास्तव में मौजूद हैं। उदाहरण के लिए सभी कॉल क्रमशः और के GetValueलिए बदल जाएगा ।(String)GetValue(Int)GetValue

सी # में, List<string>और List<int>दो अलग-अलग प्रकार हैं। वे विनिमेय नहीं हैं, और उनकी प्रकार-सुरक्षा रनटाइम में भी लागू की जाती है। कोई फर्क नहीं पड़ता कि आप क्या करते हैं, कभी भी काम नहींnew List<int>().Add("SomeString") करेगा - अंतर्निहित भंडारण वास्तव में हैList<int> कुछ पूर्णांक सरणी, जबकि जावा में, यह जरूरी एक है objectसरणी। C # में, कोई कास्ट शामिल नहीं हैं, कोई बॉक्सिंग आदि नहीं हैं।

यह भी स्पष्ट करना चाहिए कि C # जावा के साथ क्यों नहीं कर सकता है SomeType<?>। जावा में, सभी जेनेरिक प्रकार " SomeType<?>एंड " से व्युत्पन्न होते हैं जो बिल्कुल उसी प्रकार के होते हैं। C # में, सभी विभिन्न विशिष्ट SomeType<T>s अपने अलग प्रकार के होते हैं। संकलन-समय की जाँच को हटाकर, (और वास्तव में, इसका मतलब यह है कि "दिए गए सामान्य प्रकार के संकलन समय की उपेक्षा करें") के SomeType<Int>बजाय पास करना संभव है । C # में, यह संभव नहीं है, यहां तक ​​कि व्युत्पन्न प्रकारों के लिए भी नहीं (अर्थात, आप ऐसा नहीं कर सकते हैं , हालांकि इससे प्राप्त होता है )।SomeType<String>SomeType<?>List<object> list = (List<object>)new List<string>();stringobject

दोनों कार्यान्वयन में उनके पेशेवरों और विपक्ष हैं। कुछ समय रहा है जब मैंने SomeType<?>C # में एक तर्क के रूप में अनुमति देने में सक्षम होने के लिए प्यार किया है, लेकिन यह सिर्फ सी # जेनरिक के काम करने के तरीके को समझ में नहीं आता है।


2
ठीक है, आप C # के प्रकारों का उपयोग कर सकते हैं List<>, Dictionary<,>और इसी तरह, लेकिन उस और दी गई ठोस सूची या शब्दकोश के बीच का अंतर पुल के लिए काफी थोड़ा सा प्रतिबिंब लेता है। इंटरफेस पर विविधता कुछ मामलों में मदद करती है जहां हम एक बार उस अंतर को आसानी से पाटना चाहते थे, लेकिन सभी को नहीं।
जॉन हन्ना

2
@JonHanna आप List<>एक नए विशिष्ट सामान्य प्रकार को त्वरित करने के लिए उपयोग कर सकते हैं - लेकिन इसका मतलब यह है कि आप जो विशिष्ट प्रकार चाहते हैं, उसका निर्माण कर सकते हैं। List<>उदाहरण के लिए, आप एक तर्क के रूप में उपयोग नहीं कर सकते । लेकिन हां, कम से कम यह आपको प्रतिबिंब का उपयोग करके अंतर को पाटने की अनुमति देता है।
लुआं

.NET फ्रेमवर्क में तीन हार्ड-कोडित जेनेरिक अवरोध हैं जो भंडारण-स्थान प्रकार नहीं हैं; अन्य सभी बाधाएँ भंडारण-स्थान प्रकार की होनी चाहिए। इसके अलावा, केवल एक सामान्य प्रकार Tएक भंडारण-स्थान-प्रकार की बाधा Uको संतुष्ट कर सकता है जब Tऔर Uएक ही प्रकार के होते हैं, या Uएक ऐसा प्रकार होता है जो एक उदाहरण के संदर्भ को पकड़ सकता है T। यह प्रकार के भंडारण स्थान का सार्थक रूप से संभव नहीं SomeType<?>होगा, लेकिन सिद्धांत रूप में उस प्रकार का एक सामान्य बाधा होना संभव होगा।
सुपरकैट

1
यह सच नहीं है कि संकलित जावा बाइटकोड में जेनरिक की कोई धारणा नहीं है। यह सिर्फ इतना है कि वर्ग उदाहरणों में जेनरिक की कोई धारणा नहीं है। यह एक महत्वपूर्ण अंतर है; मैंने पहले इस बारे में programmers.stackexchange.com/questions/280169/… पर लिखा है , यदि आप रुचि रखते हैं।
बर्बाद करें

2

संशोधन एक वस्तु-उन्मुख मॉडलिंग अवधारणा है।

Reify एक क्रिया है जिसका अर्थ है "कुछ अमूर्त वास्तविक बनाओ"

जब आप ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग करते हैं तो वास्तविक दुनिया की वस्तुओं को सॉफ्टवेयर घटकों (जैसे विंडो, बटन, व्यक्ति, बैंक, वाहन, आदि) के रूप में मॉडल करना आम है।

अमूर्त अवधारणाओं को घटकों में भी बदलना आम है (उदाहरण के लिए WindowListener, ब्रोकर आदि)।


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

2
इसलिए मैंने इन उत्तरों को पढ़कर शिक्षित किया है। मैं अपने उत्तर में संशोधन करूंगा।
duffymo

2
यह जवाब जेपी की जेनेरिक और पैरामीट्रिक बहुरूपता में रुचि को संबोधित करने के लिए कुछ भी नहीं करता है।
एरिक जी। हागस्ट्रॉम

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

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