2008-12-09 29 views
105

यह शायद संभव नहीं है, लेकिन मैं इस वर्ग है:सी # - एक सूची में एक से अधिक सामान्य प्रकार

public class Metadata<DataType> where DataType : struct 
{ 
    private DataType mDataType; 
} 

वहाँ यह करने के लिए अधिक है, लेकिन यह आसान रखने दें। जेनेरिक प्रकार (डेटाटाइप) कहां से कथन द्वारा मूल्य प्रकार तक ही सीमित है। मैं जो करना चाहता हूं वह अलग-अलग प्रकारों (डेटाटाइप) के इन मेटाडेटा ऑब्जेक्ट्स की एक सूची है। जैसे:

List<Metadata> metadataObjects; 
metadataObjects.Add(new Metadata<int>()); 
metadataObjects.Add(new Metadata<bool>()); 
metadataObjects.Add(new Metadata<double>()); 

क्या यह भी संभव है?

public interface IMetaData { } 

public class Metadata<DataType> : IMetaData where DataType : struct 
{ 
    private DataType mDataType; 
} 
+21

मुझे आश्चर्य है कि 'सूची ' का उपयोग करने के बजाय नीचे दिए गए उत्तरों में दृष्टिकोण के लिए कोई वास्तविक लाभ है या नहीं? वे मुक्केबाजी/अनबॉक्सिंग को नहीं रोकेंगे, वे कास्टिंग की आवश्यकता को नहीं हटाएंगे, और आखिरकार, आपको 'मेटाडाटा' ऑब्जेक्ट मिल रहा है जो आपको वास्तविक 'डेटा टाइप' के बारे में कुछ नहीं बताता है, मैं एक समाधान की तलाश में था उन मुद्दों को संबोधित करें। यदि आप एक इंटरफेस/क्लास घोषित करने जा रहे हैं, तो केवल एक सामान्य सूची में कार्यान्वयन/व्युत्पन्न जेनेरिक प्रकार डालने में सक्षम होने के लिए, सिर्फ _how भिन्न_ है 'एक अर्थहीन परत होने के अलावा' सूची 'का उपयोग करने से ? –

+8

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

+1

बेशक, यदि आप .NET v4.0 या उच्चतर का उपयोग कर रहे हैं तो कॉन्वर्सिस समाधान है। 'सूची <मेटाडाटा >' चाल है। – 0b101010

उत्तर

139
public abstract class Metadata 
{ 
} 

// extend abstract Metadata class 
public class Metadata<DataType> : Metadata where DataType : struct 
{ 
    private DataType mDataType; 
} 
+4

वाह! मैंने वास्तव में नहीं सोचा था कि यह संभव था! आप एक जीवन बचतकर्ता हैं, आदमी! इसके लिए – Carl

+2

+10! मुझे नहीं पता कि यह क्यों संकलित करता है .. वास्तव में मुझे क्या चाहिए! – Odys

+0

मुझे एक ही समस्या है, लेकिन मेरी जेनेरिक क्लास एक और सामान्य वर्ग से फैली हुई है, इसलिए मैं इस समाधान के लिए किसी भी विचार पर आपके समाधान का उपयोग नहीं कर सकता? – Sheridan

69

leppie के जवाब के बाद, क्यों MetaData एक इंटरफेस नहीं Data दोनों सदस्यों को अनुमति देने के लिए प्रयोग किया जाता है:

public class Metadata<TData> : IMetadata<TData> 
{ 
    public Metadata(TData data) 
    { 
     Data = data; 
    } 

    public Type DataType 
    { 
     get { return typeof(TData); } 
    } 

    object IMetadata.Data 
    { 
     get { return Data; } 
    } 

    public TData Data { get; private set; } 
} 

आप मूल्य प्रकार को लक्षित एक संस्करण प्राप्त कर सकते हैं:

public interface IValueTypeMetadata : IMetadata 
{ 

} 

public interface IValueTypeMetadata<TData> : IMetadata<TData>, IValueTypeMetadata where TData : struct 
{ 

} 

public class ValueTypeMetadata<TData> : Metadata<TData>, IValueTypeMetadata<TData> where TData : struct 
{ 
    public ValueTypeMetadata(TData data) : base(data) 
    {} 
} 

यह सामान्य बाधाओं के किसी भी प्रकार के लिए बढ़ाया जा सकता है।

+0

कोई मुझे बता सकते हैं क्यों इस दृष्टिकोण बेहतर है – Lazlo

+24

क्योंकि कोई आम कार्यक्षमता साझा किया जाता है -।? एक आधार बर्बाद क्यों उस पर वर्ग तो? एक इंटरफेस क्योंकि आप struct में इंटरफेस को लागू कर सकते पर्याप्त – flq

+2

है। –

25

मैं भी एक गैर जेनेरिक वर्जन का इस्तेमाल किया है, new कीवर्ड का उपयोग:

public interface IMetadata 
{ 
    Type DataType { get; } 

    object Data { get; } 
} 

public interface IMetadata<TData> : IMetadata 
{ 
    new TData Data { get; } 
} 

स्पष्ट इंटरफेस कार्यान्वयन

+4

+1 सिर्फ इसलिए कि आप दिखा रहे हैं यह ('DataType' और' कैसे उपयोग करने के लिए ऑब्जेक्ट डेटा' ने बहुत मदद की) – Odys

+4

उदाहरण के लिए मैं लिखने में सक्षम नहीं हूं 'Deserialize < metadata.DataType> (metadata.Data); '। यह मुझे बताता है * प्रतीक मेटाडाटा * हल नहीं कर सकता। एक सामान्य विधि के लिए इसका उपयोग करने के लिए डेटाटाइप को कैसे पुनर्प्राप्त करें? –

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