आम तौर पर संशोधन का अर्थ है (कंप्यूटर विज्ञान के बाहर) "कुछ वास्तविक बनाने के लिए"।
यदि हम भाषा में ही इसके बारे में जानकारी तक पहुँच सकते हैं, तो प्रोग्रामिंग में, कुछ का पुनरावलोकन किया जाता है।
कुछ सी # के दो पूरी तरह से गैर-जेनरिक-संबंधित उदाहरणों के लिए सी # करता है और पुन: लागू नहीं होता है, चलो तरीकों और मेमोरी एक्सेस का उपयोग करें।
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 क्योंकि कि उनके और सामान्य प्रकार के बीच एक अंतर है)।