2009-04-01 5 views
65

सी ++ टेम्पलेट्स में, कोई निर्दिष्ट कर सकता है कि एक निश्चित प्रकार पैरामीटर डिफ़ॉल्ट है। अर्थात। जब तक स्पष्ट रूप से निर्दिष्ट नहीं किया जाता है, तो यह टाइप टीक्या सी # जेनेरिक में "डिफ़ॉल्ट" टाइप पैरामीटर के लिए कोई उचित दृष्टिकोण है?

का उपयोग करेगा सी # में किया जा सकता है या अनुमानित किया जा सकता है?

मैं की तरह कुछ के लिए देख रहा हूँ:

public class MyTemplate<T1, T2=string> {} 

तो उस प्रकार का एक उदाहरण है कि स्पष्ट रूप से निर्दिष्ट नहीं है T2: अनिवार्य रूप से

MyTemplate<int> t = new MyTemplate<int>(); 

होगा:

MyTemplate<int, string> t = new MyTemplate<int, string>(); 

आखिरकार मैं ऐसे मामले को देख रहा हूं जिसमें एक टेम्पलेट है जो काफी व्यापक रूप से है sed, लेकिन मैं एक अतिरिक्त प्रकार पैरामीटर के साथ विस्तार करने पर विचार कर रहा हूँ। मैं अनुमान लगा सकता हूं, मुझे लगता है, लेकिन अगर मैं इस नस में अन्य विकल्प थे तो मैं उत्सुक था।

उत्तर

61

सबक्लासिंग सबसे अच्छा विकल्प है।

मैं अपने मुख्य सामान्य वर्ग उपवर्ग हैं: एक विशिष्ट वर्ग

class MyGeneric<T> : BaseGeneric<T, string>

यह एक ही स्थान पर (आधार वर्ग) में अपने तर्क रखने के लिए आसान हो जाता है के साथ

class BaseGeneric<T,U>

, लेकिन उपयोग विकल्पों दोनों प्रदान करना भी आसान है। कक्षा के आधार पर, ऐसा होने के लिए शायद बहुत कम अतिरिक्त काम की आवश्यकता है।

+1

आह की तरह एक वर्ग अधिभार बना सकते हैं ... कि समझ में आता है।टाइप पैरामीटर एक अद्वितीय हस्ताक्षर प्रदान करते हैं, तो टाइप नाम समान होने की अनुमति है? – el2iot2

+2

@ee: हां, पैरामीटर पैरामीटर गिनती द्वारा 'अधिभार योग्य' हैं। –

+0

@ee: हाँ, लेकिन मैं ऐसा करने से सावधान रहूंगा। ऐसा करने के लिए .NET में यह "कानूनी" है, लेकिन इससे भ्रम पैदा हो सकता है। मैं स्ट्रिंग व्युत्पन्न प्रकार का नाम मुख्य जेनेरिक वर्ग के समान होना चाहिए (इसलिए यह स्पष्ट है कि यह क्या है/ढूंढना आसान है), लेकिन एक ऐसा नाम जो यह स्पष्ट करता है कि यह एक स्ट्रिंग है। –

6

सी # ऐसी सुविधा का समर्थन नहीं करता है।

जैसा कि आपने कहा था, आप इसे उपclass कर सकते हैं (यदि यह मुहरबंद नहीं है, और सभी कन्स्ट्रक्टर घोषणाओं को डुप्लिकेट करें) लेकिन यह एक पूरी तरह से अलग बात है।

1

दुर्भाग्य से सी # जो आप करने का प्रयास कर रहे हैं उसका समर्थन नहीं करता है। यह लागू करने के लिए एक कठिन विशेषता होगी कि पैरामीटर के लिए डिफ़ॉल्ट प्रकार को सामान्य बाधाओं का पालन करना होगा और सीएलआर ने टाइप-सुरक्षा सुनिश्चित करने की कोशिश करते समय सिरदर्द बनाएगा।

+1

वास्तव में नहीं। यह एक विशेषता के साथ किया जा सकता था (जैसे VB.NET में डिफ़ॉल्ट पैरामीटर) और संकलक संकलन समय पर इसे प्रतिस्थापित करें। प्राथमिक कारण सी # डिजाइन लक्ष्यों है। –

+0

संकलक को यह सुनिश्चित करना है कि डिफ़ॉल्ट पैरामीटर सामान्य बाधाओं को पूरा करता है। इसके अलावा डिफ़ॉल्ट पैरामीटर एक सामान्य बाधा होगी क्योंकि विधि में प्रकार पैरामीटर के बारे में किए गए किसी भी धारणा के लिए यह आवश्यक होगा कि किसी भी गैर-डिफ़ॉल्ट प्रकार पैरामीटर से प्राप्त हो। –

+0

@Andrew, डिफ़ॉल्ट पैरामीटर को सामान्य बाधा नहीं होना चाहिए। इस C++ में डिफ़ॉल्ट टेम्पलेट मानकों की तरह अधिक व्यवहार करने के लिए तो automatonic की क्लास पर विस्तार यह बिल्कुल ठीक करते होगा तो: MyTemplate एक्स = अशक्त क्योंकि टी 2, कोई सामान्य की कमी है तो नाव स्ट्रिंग के डिफ़ॉल्ट प्रकार के बावजूद ठीक है । इस तरह डिफ़ॉल्ट टेम्पलेट पैरामीटर मायटेम्प्लेट को MyTemplate के लिए शॉर्टेंड के रूप में लिखने के लिए अनिवार्य रूप से केवल "वाक्य रचनात्मक चीनी" हैं। –

13

एक समाधान उपclassing है। इसके बजाय मैं इसका उपयोग करूंगा, फैक्ट्री विधियां (var कीवर्ड के साथ संयुक्त) है।

public class MyTemplate<T1,T2> 
{ 
    public MyTemplate(..args..) { ... } // constructor 
} 

public static class MyTemplate{ 

    public static MyTemplate<T1,T2> Create<T1,T2>(..args..) 
    { 
     return new MyTemplate<T1, T2>(... params ...); 
    } 

    public static MyTemplate<T1, string> Create<T1>(...args...) 
    { 
     return new MyTemplate<T1, string>(... params ...); 
    } 
} 

var val1 = MyTemplate.Create<int,decimal>(); 
var val2 = MyTemplate.Create<int>(); 

ऊपर के उदाहरण val2 में प्रकार MyTemplate<int,string>की है और नहीं एक प्रकार से व्युत्पन्न।

एक प्रकार class MyStringTemplate<T>:MyTemplate<T,string>MyTemplate<T,string> जैसा ही नहीं है। यह कुछ परिदृश्यों में कुछ समस्याएं पैदा कर सकता है। उदाहरण के लिए आप MyTemplate<T,string> से MyStringTemplate<T> का उदाहरण नहीं डाल सकते हैं।

+3

यह सबसे उपयोगी दृष्टिकोण है। बहुत अच्छा समाधान –

8

आप भी तो

public class MyTemplate<T1, T2> { 
    public T1 Prop1 { get; set; } 
    public T2 Prop2 { get; set; } 
} 

public class MyTemplate<T1> : MyTemplate<T1, string>{} 
+0

देर से उत्तर पोस्ट करने से पहले कृपया अन्य उत्तरों को पढ़ें, क्योंकि शायद आपका समाधान दूसरों के जैसा ही है। –

+4

स्वीकृत उत्तर अलग-अलग नाम के साथ एक वर्ग बना रहा था, मेरा समाधान उसी वर्ग को ओवरलोड कर रहा है – Moes

+1

नहीं, दोनों एक नई कक्षा बना रहे हैं। नाम यहां कोई फर्क नहीं पड़ता। 'MyTemplate ' 'MyTemplate 'से एक अलग वर्ग है, न तो' अन्य टेम्पलेट '। –

संबंधित मुद्दे