दिलचस्प पोस्ट
एक जावास्क्रिप्ट स्ट्रिंग एसक्यूएल दोस्ताना बनाने GOTO कहां है: EOF वापस आती है? Math.pow (0, 0) === 1 क्यों है? सबलेट फिल्टर का उपयोग करके प्रतिक्रिया में सामग्री डालने के लिए एक उदाहरण की तलाश में डुप्लिकेट प्रतीक त्रुटि C ++ जावा: BufferedImage बाइट सरणी और वापस करने के लिए आईओएस फ़ायरबेज पुश नोटिफिकेशन: फायरबेज उपयोगकर्ता के डिवाइस टोकन और नोटिफिकेशन भेजने के लिए कैसे करें वीबीए लघु-सर्किट `और` विकल्प कुकीज़ को रेखांकित करता है, प्रारंभ तिथि सेट करें और तिथि की समय सीमा समाप्त करें उपयोगकर्ता प्रमाणीकरण और पासवर्ड सुरक्षा के लिए PHP सर्वोत्तम प्रथाएं मैं पर्ल मॉड्यूल के एक विशिष्ट संस्करण को कैसे स्थापित कर सकता हूं? एनजी-पैटर्न का उपयोग करके कोणीय जेएस में ईमेल आईडी को कैसे मान्य किया जाए LINQ और C # का उपयोग कर Microsoft Access MDB डेटाबेस की क्वेरी करें कैसे ककड़ी सुविधा फ़ाइल समानांतर को निष्पादित करें मैं C ++ 11 में alignas () का उपयोग कहां कर सकता / सकती हूं?

एक विशिष्ट कन्स्ट्रक्टर के लिए एक सामान्य प्रकार पैरामीटर को सीमित करना

मैं जानना चाहता हूं कि एक सामान्य प्रकार पैरामीटर पर नई बाधा केवल मापदंडों के बिना ही लागू हो सकती है, अर्थात, पैरामीटर वाला कन्स्ट्रक्टर बनाने के लिए एक प्रकार की बाधा हो सकती है, लेकिन कोई ऐसा वर्ग नहीं बना सकता जो कहने के लिए एक कन्स्ट्रक्टर पैरामीटर के रूप में एक पूर्णांक प्राप्त करता है मुझे इसके आसपास तरीके पता है, प्रतिबिंब या कारखाने के पैटर्न का उपयोग कर, जो ठीक काम करता है, ठीक है। लेकिन मैं सचमुच जानना चाहता हूं, क्योंकि मैं इसके बारे में सोच रहा था और मैं वास्तव में एक पैरामीटर वाले निर्माता के बीच अंतर नहीं सोच सकता है और एक पैरामीटर के साथ जो इस प्रतिबंध को नई बाधा पर उचित ठहराएगा। मैं क्या खो रहा हूँ? बहुत बहुत धन्यवाद


तर्क 1: कन्स्ट्रक्टर्स तरीके हैं

@ एरिक: मुझे एक सेकेंड के लिए आपके साथ यहां जाने दो:

कन्स्ट्रक्टर्स तरीके हैं

तो मुझे लगता है कि अगर कोई मुझे पसंद करता है तो कोई भी वस्तु नहीं देगा:

public interface IReallyWonderful { new(int a); string WonderMethod(int a); } 

लेकिन एक बार मेरे पास ये है, तो मैं जाता हूं:

 public class MyClass<T> where T : IReallyWonderful { public string MyMethod(int a, int b) { T myT = new T(a); return myT.WonderMethod(b); } } 

जो मैं पहली जगह में करना चाहता था तो, खेद है, लेकिन नहीं, कन्स्ट्रक्टर तरीके नहीं हैं , या कम से कम ठीक नहीं हैं

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

एक अकादमिक (मेरी) दृष्टिकोण से, और वह है, कार्यान्वयन की लागत के किसी भी संबंध के बिना, वास्तव में सवाल है (मैं इसे पिछले कुछ घंटों में इसे पूरा कर लिया है):

कन्स्ट्रक्टर को कक्षा के क्रियान्वयन के भाग के रूप में, या सिमेंटिक अनुबंध के भाग के रूप में माना जाएगा (उसी तरह एक अंतरफलक को सिमेंटिक अनुबंध माना जाता है)।

यदि हम कंस्ट्रक्टर को कार्यान्वयन के हिस्से के रूप में मानते हैं, तो, एक जेनेरिक प्रकार के पैरामीटर के निर्माता को रोकना एक सामान्य चीज़ नहीं है, क्योंकि यह एक ठोस क्रियान्वयन के लिए आपके सामान्य प्रकार को बांधना चाहती है, और लगभग यही कह सकता है कि सभी पर जेनेरिक का उपयोग करें?

कार्यान्वयन के हिस्से के रूप में कन्स्ट्रक्टर का उदाहरण ( ITransformer द्वारा परिभाषित सिमेंटिक अनुबंध के भाग के रूप में निम्नलिखित कन्स्ट्रक्टरों में से किसी को निर्दिष्ट करने में कोई मतलब नहीं है):

 public interface ITransformer { //Operates with a and returns the result; int Transform(int a); } public class PlusOneTransformer : ITransformer { public int Transform(int a) { return a + 1; } } public class MultiplyTransformer : ITransformer { private int multiplier; public MultiplyTransformer(int multiplier) { this.multiplier = multiplier; } public int Transform(int a) { return a * multiplier; } } public class CompoundTransformer : ITransformer { private ITransformer firstTransformer; private ITransformer secondTransformer; public CompoundTransformer(ITransformer first, ITransformer second) { this.firstTransformer = first; this.secondTransformer = second; } public int Transform(int a) { return secondTransformer.Transform(firstTransformer.Transform(a)); } } 

समस्या यह है कि कन्स्ट्रक्टर को सिमेंटिक अनुबंध के हिस्से के रूप में भी माना जा सकता है, जैसे:

 public interface ICollection<T> : IEnumerable<T> { new(IEnumerable<T> tees); void Add(T tee); ... } 

इसका मतलब है, यह तत्वों के अनुक्रम से एक संग्रह बनाने के लिए हमेशा सही है, सही है? और वह सिमेंटिक अनुबंध का एक बहुत मान्य भाग बनायेगा, है ना?

मुझे, शेयरधारक पैसे के बुद्धिमानी के व्यय के बारे में किसी भी पहलू को ध्यान में रखते हुए, कंसल्टेंटर्स को सिमेंटिक कॉन्ट्रैक्ट्स के हिस्से के रूप में जाने की इजाजत देनी होगी। कुछ डेवलपर इसे खराब कर देता है और एक निश्चित रूप से एक गलत तरीके से गलत कन्स्ट्रक्टर बनाने के लिए बाध्य करता है, ठीक है, एक ही डेवलपर से अंतर क्या है जो एक अर्थपूर्ण गलत ऑपरेशन जोड़ रहा है? सब के बाद, अर्थ अनुबंध है, क्योंकि हम सब सहमत हैं, और क्योंकि हम सब हमारे पुस्तकालयों को वास्तव में अच्छी तरह से लिखते हैं;)


तर्क 2: कंसल्टेंट्स को हल करते समय अनुमानित समस्याएं

@ सुपरकॉट कुछ उदाहरणों को सेट करने का प्रयास कर रहा है कि कैसे (टिप्पणी से उद्धरण)

आश्चर्यजनक व्यवहार के परिणामस्वरूप बिना कन्स्ट्रक्टर बाधाओं को कैसे ठीक करना चाहिए, यह भी परिभाषित करना कठिन होगा

लेकिन मुझे सचमुच असहमत होना चाहिए। सी # में (अच्छी तरह से, .नेट में) "कैसे एक पेंगुइन मक्खी बनाने के लिए" जैसे आश्चर्य? बस ऐसा नहीं होता है कंपाइलर विधि कॉल का समाधान कैसे करता है, और यदि संकलक इसे हल नहीं कर सकता, तो यह बहुत सीधा नियम हैं, ठीक है, यह पारित नहीं होगा, यह संकलन नहीं करेगा।

उनका अंतिम उदाहरण था:

यदि वे भ्रष्ट हैं, तो एक परेशानी में हल हो जाता है जिससे कन्स्ट्रक्टर को बुलाया जाना चाहिए अगर एक सामान्य प्रकार में नया (कैट, टोयोटाटेरसेल) बाधा है, और वास्तविक प्रकार में केवल कंसल्टर्स नया (पशु, टोयोटाटासेल) और नया (बिल्ली, ऑटोमोबाइल) है।

अच्छा, यह कोशिश करें (मेरी राय में @ सुपरकैट द्वारा प्रस्तावित की गई ऐसी स्थिति)

 class Program { static void Main(string[] args) { Cat cat = new Cat(); ToyotaTercel toyota = new ToyotaTercel(); FunnyMethod(cat, toyota); } public static void FunnyMethod(Animal animal, ToyotaTercel toyota) { Console.WriteLine("Takes an Animal and a ToyotaTercel"); } public static void FunnyMethod(Cat cat, Automobile car) { Console.WriteLine("Takes a Cat and an Automobile"); } } public class Automobile { } public class ToyotaTercel : Automobile { } public class Animal { } public class Cat : Animal { } 

और, वाह, यह त्रुटि के साथ संकलन नहीं करेगा

कॉल निम्नलिखित विधियों या गुणों के बीच अस्पष्ट है: 'TestApp.Program.FunnyMethod (TestApp.Animal, TestApp.ToyotaTercel)' और 'TestApp.Program.FunnyMethod (TestApp.Cat, TestApp.Automobile)'

मुझे नहीं पता कि परिणाम अलग क्यों होना चाहिए यदि समान समस्याएं पैरामीटरबद्ध कन्स्ट्रक्टर बाधाओं के समाधान के साथ उत्पन्न होती हैं, तो ऐसा:

 class Program { static void Main(string[] args) { GenericClass<FunnyClass> gc = new GenericClass<FunnyClass>(); } } public class Automobile { } public class ToyotaTercel : Automobile { } public class Animal { } public class Cat : Animal { } public class FunnyClass { public FunnyClass(Animal animal, ToyotaTercel toyota) { } public FunnyClass(Cat cat, Automobile car) { } } public class GenericClass<T> where T: new(Cat, ToyotaTercel) { } 

अब, ज़ाहिर है, कंपाइलर कंस्ट्रक्टर पर बाधा नहीं रख सकता है, लेकिन अगर ऐसा हो सकता है, तो लाइन पर GenericClass<FunnyClass> gc = new GenericClass<FunnyClass>(); पहले उदाहरण को संकलित करने की कोशिश करते समय मिलती-जुलती है, जो कि FunnyMethod

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

Solutions Collecting From Web of "एक विशिष्ट कन्स्ट्रक्टर के लिए एक सामान्य प्रकार पैरामीटर को सीमित करना"

पाठ्यक्रम से मुझसे कर्क वाल्ले की बोली सभी आवश्यक औचित्य है; मौजूदा सुविधाओं के लिए हमें औचित्य प्रदान करने की आवश्यकता नहीं है सुविधाओं में भारी लागत है

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

के साथ शुरू करने के लिए: अधिक सामान्य सुविधा पर विचार करें। कन्स्ट्रक्टर्स तरीके हैं यदि आप उम्मीद करते हैं कि "एक प्रकार का तर्क एक कंसट्रक्टर है जो एक इंट लेता है" तो आप यह कहने के लिए भी उचित नहीं हैं कि "प्रकार तर्क में क्यू का एक सार्वजनिक तरीका होना चाहिए जो कि दो पूर्णांक लेता है और एक स्ट्रिंग? "

 string M<T>(T t) where T has string Q(int, int) { return tQ(123, 456); } 

क्या यह आपको एक बहुत सामान्य चीज़ के रूप में मारता है? ऐसा लगता है कि जेनेरिक के विचार के प्रति इस प्रकार की बाधा है

यदि सुविधा विधियों के लिए एक बुरा विचार है, तो क्यों यह उन विधियों के लिए एक अच्छा विचार है जो कन्स्ट्रक्टर होते हैं ?

इसके विपरीत, अगर यह विधियों और कन्स्ट्रक्टरों के लिए एक अच्छा विचार है, तो वहां क्यों रोकें?

 string M<T>(T t) where T has a field named x of type string { return tx; } 

मैं कहता हूं कि हमें पूरी सुविधा भी करनी चाहिए या इसे बिल्कुल भी नहीं करना चाहिए । यदि विशेष रूप से कंसल्टेंट्स के प्रकारों को सीमित करने में सक्षम होना जरूरी है, तो आम तौर पर सदस्यों के आधार पर पूरी सुविधा और प्रकार सीमित करें और कंसल्टर्स न केवल।

यह सुविधा निश्चित रूप से डिजाइन, कार्यान्वयन, परीक्षण, दस्तावेज़ और बनाए रखने के लिए बहुत अधिक महंगा है।

दूसरा बिंदु: मान लें कि हमने इस सुविधा को लागू करने का निर्णय लिया है, या तो "बस कंस्ट्रक्टर" संस्करण या "कोई सदस्य" संस्करण। हम क्या कोड उत्पन्न करते हैं? जेनेरिक कोडन के बारे में बात यह है कि इसे ध्यानपूर्वक डिजाइन किया गया है ताकि आप एक बार स्थिर विश्लेषण कर सकें और इसके साथ किया जाए। लेकिन आईएल में "कंसट्रक्टर को कॉल करने का वर्णन करने का कोई मानक तरीका नहीं है" हमें या तो आईएल को एक नई अवधारणा जोड़नी होगी, या कोड उत्पन्न करना ताकि जेनेरिक कन्स्ट्रक्टर का इस्तेमाल किया प्रतिबिंब का उपयोग किया जा सके

पूर्व महंगा है; आईएल में एक मूल अवधारणा को बदलना बहुत ही महंगा है। उत्तरार्द्ध (1) धीमा है, (2) पैरामीटर बॉक्स, और (3) वह कोड है जिसे आप खुद लिख सकते थे यदि आप कन्स्ट्रक्टर को खोजने के लिए प्रतिबिंब का उपयोग करने जा रहे हैं और इसे कॉल करते हैं, तो उस कोड को लिखें, जो कन्स्ट्रक्टर को खोजने के लिए प्रतिबिंब का उपयोग करता है और इसे कॉल करता है। अगर यह कोड जन रणनीति है तो एकमात्र लाभ जो बाधा को प्रदान करता है यह है कि एक प्रकार तर्क को पारित करने का बग़ा जिसके पास एक सार्वजनिक सीटीओर नहीं है जो कि इंट्रेट को रनटाइम के बजाय संकलन समय पर पकड़ा जाता है । आपको जेनेरिक के अन्य लाभों में से कोई भी लाभ नहीं मिलता है, जैसे कि प्रतिबिंब और मुक्केबाजी दंडों को टालना

सारांश

यह इस प्रश्न पर वर्तमान जानकारी और कार्यवाही को पकड़ने और इसे एक उत्तर के रूप में पेश करने का एक प्रयास है।

मैं जेनेरिक को सी # (एक सी + + टेम्पलेट्स पृष्ठभूमि से आ रहा है) के सबसे शक्तिशाली और सुरुचिपूर्ण पहलुओं में से एक के साथ जोड़ता हूं। where T : Foo महान है क्योंकि यह टी की क्षमता का परिचय देता है जबकि अभी भी संकलन समय पर इसे फू करने के लिए बाध्य है। कई मामलों में, मैंने अपना कार्यान्वयन सरल बना दिया है। सबसे पहले, मैं इस तरह से जेनेरिक प्रकारों का उपयोग करने के बारे में थोड़ा चिंतित था, जेनेरिक को कोड के माध्यम से बढ़ने का कारण बन सकता है, लेकिन मैंने इसे ऐसा करने की अनुमति दी है और लाभ ने किसी भी डाउनसाइड्स से अधिक प्रभावित किया है हालांकि, अमूर्त हमेशा नीचे गिरता है जब कोई सामान्य प्रकार के निर्माण की बात आती है जो पैरामीटर लेती है

समस्या

जब एक जेनेरिक वर्ग को बाधित किया जाता है, तो आप यह संकेत दे सकते हैं कि जेनेरिक में एक पैरासेलेबल कन्स्ट्रक्टर होना चाहिए और उसके बाद इसे इन्स्तांत करना होगा:

 public class Foo<T> where T : new() { public void SomeOperation() { T something = new T(); ... } } 

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

यह माइक्रोसॉफ्ट कनेक्ट पर ये लिंक है, माइक्रोसॉफ्ट कनेक्ट के बारे में ये कुछ भी पता है, जैसे यहाँ एक नमूना है (सवाल पूछे गए उलझन वाले ढेर स्टैक ओवरफ्लो उपयोगकर्ताओं की गिनती नहीं) यहाँ यहां यहां यहां ।

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

वर्कआराउंड

तीन मुख्य प्रकार के समाधान हैं, जिनमें से कोई भी आदर्श नहीं हैं: –

  1. कारखानों का उपयोग करें इसके लिए बॉयलरप्लेट कोड और ओवरहेड की एक पूरी बहुत आवश्यकता है
  2. एक्टिवेटर का उपयोग करें। क्रेताइंसेंस (टाइपफ (टी), आरजीएल, एजी 1, एजीआर 2, …) । यह मेरी कम से कम पसंदीदा है क्योंकि प्रकार की सुरक्षा खो जाती है। क्या होगा अगर आप नीचे ट्रैक के कंस्ट्रक्टर को एक पैरामीटर जोड़ते हैं? आपको एक रनटाइम अपवाद मिलता है
  3. फ़ंक्शन / क्रिया दृष्टिकोण का उपयोग करें और यहाँ यह मेरी पसंदीदा है क्योंकि यह प्रकार सुरक्षा को बरकरार रखता है और कम बॉयलरप्लेट कोड की आवश्यकता होती है। हालांकि, यह अभी भी उतना सरल नहीं है जितना कि नए टी (ए, बी, सी) और एक सामान्य अमूर्त के रूप में अक्सर कई वर्गों को फैलाया जाता है, जो कक्षा को जानता है वह अक्सर कक्षा से कुछ कक्षाएं दूर होता है जिसे इसे तुरंत इन्स्तांत करने की आवश्यकता होती है func अनावश्यक कोड में जिसके परिणामस्वरूप के आसपास पारित हो गया

स्पष्टीकरण

माइक्रोसॉफ्ट कनेक्ट पर एक मानक प्रतिक्रिया प्रदान की जाती है:

"आपके सुझाव के लिए धन्यवाद। माइक्रोसॉफ्ट ने सामान्य प्रकार की बाधा शब्दों के साथ-साथ इस क्षेत्र में अपना काम करने पर भी कई सुझाव प्राप्त किए हैं। हालांकि इस समय माइक्रोसॉफ्ट किसी उपक्रम को नहीं दे सकता है जो इस क्षेत्र में बदलाव लाएगा भविष्य के उत्पाद के रिलीज का हिस्सा बनो। आपका सुझाव इस क्षेत्र में ड्राइव निर्णयों की सहायता के लिए नोट किया जाएगा। इस बीच में कोड नमूना नीचे … "

वर्कअराउंड वास्तव में सभी विकल्पों का अनुशंसित समाधान नहीं है क्योंकि यह सुरक्षित प्रकार नहीं है और रनटाइम अपवाद में नतीजे हैं यदि आप कभी भी कंस्ट्रक्टर के लिए एक अन्य पैरामीटर जोड़ते हैं

इस सबसे स्टैक अतिप्रवाह पोस्ट में एरिक लिपर ने मुझे सबसे अच्छा विवरण मिल सकता है I मैं इस उत्तर की बहुत सराहना करता हूं, लेकिन मुझे लगता है कि उपयोगकर्ता स्तर पर और फिर तकनीकी स्तर पर (संभवतः उन लोगों द्वारा जो इंटर्न के बारे में मुझसे अधिक जानते हैं) के लिए और अधिक चर्चा की आवश्यकता है।

मैंने हाल ही में देखा है कि इस लिंक में मैड्स टॉगरसन द्वारा एक अच्छा और विस्तार है (देखें "माइक्रोसॉफ्ट द्वारा 3/31/2009 को 3:29 बजे पोस्ट किया गया")।

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

सुझाव

विवादास्पद लाभ के साथ-साथ कार्यान्वयन में कठिनाई के बावजूद, मैं इसकी सराहना कर सकता हूं, लेकिन निम्नलिखित बिंदुओं को बनायेगा: –

  1. रनटाइम (इस मामले में प्रकार सुरक्षा) के बजाय समय संकलन पर कीड़े पकड़ने में बहुत अच्छा मूल्य है।
  2. ऐसा लगता है कि ऐसा कोई अन्य विकल्प नहीं है जो बहुत सख्त नहीं है। इस पर कुछ सुझाव दिए गए हैं कि यह कैसे लागू किया जा सकता है। विशेष रूप से, जॉन स्कीट ने इसे हल करने का एक तरीका के रूप में 'स्थिर इंटरफेस' का प्रस्ताव रखा और ऐसा प्रतीत होता है कि स्पष्ट सदस्य बाधाएं पहले से ही सीएलआर में मौजूद हैं, लेकिन सी # में नहीं, यहाँ की टिप्पणियां और यहां चर्चा देखें। इसके अलावा, मनमाना सदस्य प्रतिबंधों के बारे में एरिक लिपर की प्रतिक्रिया में केवीबी द्वारा टिप्पणी।

स्थिति

जहाँ तक मैं बता सकता हूं, किसी भी प्रकार के रूप में होने के बारे में नहीं।

यदि कोई एक सामान्य प्रकार T साथ एक विधि चाहता है, जिसके उदाहरणों को एक एकल पैरामीटर का उपयोग करके बनाया जा सकता है, तो एक को विधि टाइप करने के अलावा, T अलावा, Func<int, T> या अन्यथा उपयुक्त-परिभाषित होना चाहिए इंटरफ़ेस, शायद कुछ ऐसा प्रयोग करना:

 static class IFactoryProducing<ResultType> { interface WithParam<PT1> { ResultType Create(PT1 p1); } interface WithParam<PT1,PT2> { ResultType Create(PT1 p1, PT2 p2); } } 

(यदि बाहरी IFactoryProducing<T>.WithParam<int> क्लास को इंटरफ़ेस के रूप में घोषित किया जा सकता है, लेकिन IFactoryProducing<T>.WithParam<int> । कोड के साथ अच्छा लगता होगा IFactory<int,T> से स्पष्ट रूप से IFactory<int,T> IFactoryProducing<T>.WithParam<int> लगता है (बाद में यह अस्पष्ट है कि किस प्रकार के पैरामीटर और जो परिणाम है)।

किसी भी मामले में, जब भी कोई एआरयूड प्रकार T ए पास करता है तो एक उपयुक्त फैक्टरी प्रतिनिधि या इंटरफ़ेस के पास ही गुजरता है, एक 99% प्राप्त कर सकता है जो कि पैरामीटरबद्ध कन्स्ट्रक्टर बाधाओं के साथ हासिल कर सकता है। रन-टाइम की लागत को प्रत्येक निर्माण योग्य प्रकार से फैमिली के स्थैतिक उदाहरण उत्पन्न करने से कम किया जा सकता है, इसलिए किसी भी प्रकार के लूपिंग संदर्भ में फ़ैक्टरी के इंस्टेंस को बनाने के लिए आवश्यक नहीं होगा।

बीटीडब्लू, सुविधा की लागत से परे, लगभग निश्चित रूप से कुछ महत्वपूर्ण सीमाएं होती हैं जो वैकल्पिक हल से कम बहुमुखी होती हैं। यदि कंस्ट्रक्टर बाधाएं पैरामीटर प्रकारों के संबंध में उल्लिखित नहीं हैं, तो कंसट्रक्टर बाधा के लिए आवश्यक सटीक प्रकार के लिए एक पैरामीटर को एक पैरामीटर को पास करने के लिए आवश्यक हो सकता है, इसके उपयोग के लिए पैरामीटर के वास्तविक प्रकार के अतिरिक्त; जब तक कोई ऐसा करता है, कोई भी फैक्ट्री के पास हो सकता है। यदि वे भ्रष्ट हैं, तो एक परेशानी में हल हो जाता है जिससे कन्स्ट्रक्टर को बुलाया जाना चाहिए अगर एक सामान्य प्रकार में new(Cat, ToyotaTercel) बाधा है, और वास्तविक प्रकार में केवल new(Animal, ToyotaTercel) और new(Cat, Automobile)

पी एस – समस्या को स्पष्ट करने के लिए, पोषक तत्व कन्स्ट्रक्टर बाधाओं से "डबल हीरे" समस्या के भिन्नरूप हो जाते हैं। विचार करें:

 T CreateUsingAnimalAutomobile<T>() where T:IThing,new(Animal,Automobile) { ... } T CreateUsingAnimalToyotaTercel<T>() where T:IThing,new(Animal,ToyotaTercel) { return CreateUsingAnimalAutomobile<T>(); } T CreateUsingCatAutomobile<T>() where T:IThing,new(Cat,Automobile) { return CreateUsingAnimalAutomobile<T>(); } IThing thing1=CreateUsingAnimalToyotaTercel<FunnyClass>(); // FunnyClass defined in question IThing thing2=CreateUsingCatAutomobile<FunnyClass>(); // FunnyClass defined in question 

CreateUsingAnimalToyotaTercel<FunnyClass>() पर कॉल करने के लिए प्रसंस्करण में, "पशु, टोयोटाटासेल" निर्माता उस विधि के लिए बाधा को संतुष्ट करना चाहिए और उस विधि के लिए सामान्य प्रकार CreateUsingAnimalAutomobile<T>() लिए एक बाधा को पूरा करना चाहिए। CreateUsingCatAutomobile<FunnyClass>() पर कॉल करने की प्रक्रिया में, "कैट, ऑटोमोबाइल" कन्स्ट्रक्टर को उस विधि के लिए बाधा को पूरा करना चाहिए और उस विधि के लिए सामान्य प्रकार CreateUsingAnimalAutomobile<T>() लिए बाध्य होना चाहिए।

समस्या यह है कि दोनों कॉल एक ही CreateUsingAnimalAutomobile<SillyClass>() पद्धति के लिए कॉल का आह्वान करेंगे, और उस पद्धति में जानने का कोई तरीका नहीं है कि कौन से कंसट्रक्टर को आमंत्रित किया जाना चाहिए विरोधाभासी-संबंधित अस्पष्टता कंसल्टर्स के लिए अद्वितीय नहीं हैं, लेकिन ज्यादातर मामलों में उन्हें संकलन-समय बंधन के माध्यम से हल किया जाता है।

कन्स्ट्रक्टर के बारे में
इसके बारे में सोचें। आप अपने हाथ में केवल एक इंटरफ़ेस प्रकार के साथ इन्स्तांत नहीं कर सकते आप इंटरफ़ेस का उपयोग किसी ऑब्जेक्ट इंस्टेंस से बताते हैं कि उदाहरण के लिए विशिष्ट फ़ंक्शन हैं आप उदाहरण के लिए एक ctor कॉल नहीं कर सकते:

  public interface IInterface { void SomeMethod(); } public class Example1 : IInterface { public void SomeMethod() { } } public class Example2 : IInterface { public void SomeMethod() { } } public class InterfaceConsumer { private IInterface _myService; public InterfaceConsumer(IInterface service) { _myService = service; } } 

आप _myService.new() या _myService.ctor() कॉल नहीं कर सकते।