में सामान्य जेनेरिक प्रकार पैरामीटर के साथ प्रतिनिधियों को अनुकरण करना भाषा डिजाइन, पैटर्न और अर्थशास्त्र के बारे में यह एक कठिन सवाल है। कृपया, नीचे मत छोड़ो क्योंकि आप व्यावहारिक मूल्य नहीं देखते हैं।सी #
सबसे पहले, चलो फ़ंक्शंस और उनके पैरामीटर के बारे में सोचें। फिर हम अपने पैरामीटर/तर्कों और जेनेरिक कक्षाओं/कार्यों के साथ उनके प्रकार-पैरामीटर/प्रकार-तर्कों के साथ कार्यों के बीच समानताएं देखेंगे।
कार्य कुछ अनिर्दिष्ट मूल्यों "मापदंडों" कहा जाता है के साथ कोड के ब्लॉक कर रहे हैं। आप तर्क प्रदान करते हैं और परिणाम प्राप्त करते हैं।
जेनेरिक कक्षाएं कुछ अनिर्दिष्ट "प्रकार-पैरामीटर" के साथ वर्ग हैं। आप टाइप-तर्क की आपूर्ति करते हैं और फिर आप कक्षा के साथ काम कर सकते हैं - निर्माता को कॉल करें या स्थैतिक तरीकों का आह्वान करें।
जेनेरिक कार्यों गैर सामान्य कक्षाओं में कुछ अनिर्दिष्ट "प्रकार-पैरामीटर" और कुछ अनिर्दिष्ट "मूल्य-मानकों" के साथ कार्य हैं। परिणाम प्राप्त करने के लिए आप प्रकार-तर्क और मूल्य-तर्क प्रदान करते हैं।
प्रतिनिधियों विशिष्ट कार्यों के लिए पॉइंटर्स हैं। जब आप प्रतिनिधि बनाते हैं तो आप तर्क फ़ंक्शन निर्दिष्ट नहीं करते हैं, लेकिन बाद में उन्हें आपूर्ति करते हैं।
समस्या यह है कि .NET के पास सामान्य जेनेरिक टाइप-पैरामीटर के साथ जेनेरिक फ़ंक्शंस के लिए प्रतिनिधि नहीं हैं। टाइप-पैरामीटर के बाद आप टाइप-वैल्यू की आपूर्ति नहीं कर सकते हैं। हम उन प्रतिनिधियों की कल्पना कर सकते हैं जिनमें न केवल मूल्य पैरामीटर है, बल्कि टाइप-पैरामीटर भी निःशुल्क हैं।
static class SomeClass {
//generic function
public static T GetValue<T>() {
return default(T);
}
}
//creating delegate to generic function or method group
Func{TFree}<TFree> valueFactory = SomeClass.GetValue;
//creating delegate to anonymous generic function
Func{TFree}<int, List<TFree>> listFactory = {TFree}(int capacity) => new List<TFree>(capacity);
नीचे एक प्रोग्राम है जो मैं सी # में लिखने के लिए चाहते हैं के लिए [छद्म] कोड है। मैं जानना चाहता हूं कि कोई सही सी # प्रोग्राम में समान व्यवहार कैसे प्राप्त कर सकता है।
हम सी # में मुफ्त सामान्य प्रकार-पैरामीटर के साथ प्रतिनिधियों का अनुकरण कैसे कर सकते हैं?
गैर-जेनेरिक कोड के माध्यम से अभी तक अज्ञात जेनेरिक पैरामीटर के साथ जेनेरिक फ़ंक्शन [ओं] के संदर्भ/लिंक को कैसे पास कर सकते हैं?
public static class Factory { //Everything compiles fine here
public delegate ICollection<T> FactoryDelegate<T>(IEnumerable<T> values);
public static ICollection<T> CreateList<T>(IEnumerable<T> values) {
return new List<T>(values);
}
public static ICollection<T> CreateSet<T>(IEnumerable<T> values) {
return new HashSet<T>(values);
}
}
public class Worker { //non-generic class
Func{TFree}<FactoryDelegate<TFree>> _factory; //TFree is a "free" generic type paramenter
public Worker(Func{TFree}<FactoryDelegate<TFree>> factory) {
_factory = factory;
}
public ICollection<T> DoWork<T>(IEnumerable<T> values) { //generic method
return _factory{T}(values); //supplying T as the argument for type parameter TFree
}
}
public static class Program {
public static void Main() {
string[] values1 = new string[] { "a", "b", "c" };
int[] values2 = new int[] { 1, 2, 2, 2 };
Worker listWorker = new Worker(Factory.CreateList); //passing reference to generic function
Worker setWorker = new Worker(Factory.CreateSet); //passing reference to generic function
ICollection<string> result1 = listWorker.DoWork(values1);
ICollection<int> result2 = listWorker.DoWork(values2); //.Count == 4
ICollection<int> result3 = setWorker.DoWork(values2); //.Count == 2
}
}
कैसे हम प्रकार तर्क निर्दिष्ट किए बिना कार्यकर्ता वर्ग निर्माता के लिए सामान्य कार्य (Factory.CreateList और Factory.CreateSet) के लिए संदर्भ पारित देखें?तर्क टाइप करें बाद में आपूर्ति की जाती है जब सामान्य DoWork फ़ंक्शन को ठोस-टाइप किए गए सरणी के साथ बुलाया जाता है। सही कार्य का चयन करने के लिए DoWork प्रकार-तर्क का उपयोग करता है, मान-तर्क पास करता है और प्राप्त मान देता है।
अंतिम समाधान:Emulating delegates with free generic type parameters in C#
'ओपन टाइप' और विशेष रूप से 'टाइप कन्स्ट्रक्टर' शब्द देखें। – SLaks
मुझे नहीं लगता कि सी # का प्रतिबिंब या वर्कर जेनेरिक बनाने के बिना ऐसा करने का कोई तरीका है। मुझे संदेह है कि _higher- kinded type_, जो .Net समर्थन नहीं करता है, मदद करेगा। – SLaks
मुझे यकीन नहीं है, लेकिन क्या आपने इसके बजाय F # देखा है? सी # को अधिक कार्यात्मक होने के लिए मजबूर करना शायद दर्दनाक निष्पादन होगा। –