2016-10-21 13 views
6

मैं निम्न प्रकार है कहते हैं:सामान्य प्रकार वाले सरणी को कैसे घोषित किया जाए?

public class Field<T> 
{ 
    public string Name { get; set; } 
    public T Value { get; set; } 
} 

मैं एक चर कि इस तरह की फील्ड्स की एक सरणी में शामिल होंगे कैसे घोषणा कर सकते हैं?

var customFields = new Field[] 
{ 
    new Field<string> { Name = "nickname", Value = "Bob" }, 
    new Field<int> { Name = "age", Value = 42 }, 
    new Field<DateTime> { Name = "customer_since", Value = new DateTime(2000, 12, 1) } 
}; 

लेकिन मैं निम्नलिखित संकलन समय अपवाद: मैं निम्नलिखित की कोशिश की

सामान्य प्रकार 'फील्ड' का उपयोग की आवश्यकता है 1 प्रकार तर्क

मैं भी कोशिश की, लेकिन var customFields = new Field<object>[] मुझे निम्न त्रुटियां मिलती हैं:

स्पष्ट रूप से प्रकार 'फ़ील्ड' को 'एफ' में परिवर्तित नहीं कर सकता ield '

परोक्ष प्रकार कनवर्ट नहीं कर सकता' फील्ड 'को' फील्ड '

परोक्ष प्रकार कनवर्ट नहीं कर सकता' फील्ड '

+4

प्रत्येक सामान्य प्रकार, एक * अलग प्रकार * है। इसलिए, आप विभिन्न प्रकार के उदाहरणों की एक सरणी बनाने की कोशिश कर रहे हैं। यह नहीं हो सकता। यह एक सरणी बनाने की कोशिश करने जैसा है जो 'स्ट्रिंग' और' int' मानों को संग्रहीत करेगा। हालांकि, आप [covariance] (https://msdn.microsoft.com/en-us/library/dd799517 (v = vs.110) .aspx पर एक नज़र डाल सकते हैं)। –

उत्तर

12

' को 'क्षेत्र के रूप में मटीस ने कहा कि यह उस तरह से क्योंकि नहीं किया जा सकता Field<int> और Field<string> पूरी तरह से अलग प्रकार हैं। आप क्या कर सकते है:

एक आधार Field बनाएं जो सामान्य नहीं है:

public class Field 
{ 
    public string Name { get; set; } 
} 

public class Field<T> : Field 
{ 
    public T Value { get; set; } 
} 

और फिर:

var customFields = new Field[] 
{ 
    new Field<string> { Name = "nickname", Value = "Bob" }, 
    new Field<int> { Name = "age", Value = 42 }, 
    new Field<DateTime> { Name = "customer_since", Value = new DateTime(2000, 12, 1) } 
}; 

रूप मटीस टिप्पणी की एक downcasting की Value पाने के लिए की आवश्यकता होगी विभिन्न प्रकार। यदि प्रत्येक अलग-अलग प्रकार के Value के लिए प्रदर्शन करने के लिए एक विशिष्ट तर्क है, तो इसे संभालने का एक अच्छा तरीका Factory डिज़ाइन पैटर्न का उपयोग करना होगा। कारखाना प्रत्येक Field के लिए एक सही "FieldHandler<T>" के लिए वापस आ जाएगा जो कम हो जाएगा, ऑपरेशन करें और जो आवश्यक है उसे वापस कर देगा।

+5

एफवाईआई: किसी तत्व की 'वैल्यू 'संपत्ति प्राप्त करने के लिए आपको सामान्य प्रकार के लिए डाउनकास्ट करना होगा। –

+0

@MatiasCicero - Ya ... यह सच है .. –

+0

बहुत अच्छा विचार! जैसा कि मतिस ने कहा, मुझे मूल्य प्राप्त करने के लिए डालना होगा, लेकिन मेरे विशिष्ट मामले में, एक बड़ा सौदा नहीं है क्योंकि मैं केवल स्ट्रिंग, int और डेटटाइम का समर्थन करता हूं। वैसे, कोई जानता है कि क्या मैं टी को केवल इन तीन प्रकारों तक सीमित कर सकता हूं? कुछ पंक्तियों के साथ: 'जहां टी: स्ट्रिंग, int, डेटटाइम' – desautelsj

2

एक और चीज जो आप कर सकते हैं वह उन सभी प्रकारों के लिए सामान्य बेस क्लास का उपयोग करना है - ऑब्जेक्ट।

class Field 
{ 
    public string Name { get; set; } 
    public Object Value { get; set; } 
} 
var customFields = new Field[] 
{ 
    new Field { Name = "nickname ", Value = "Bob" }, 
    new Field { Name = "age", Value = 42 }, 
    new Field { Name = "customer_since", Value = new DateTime(2000, 12, 1) } 
}; 

हालांकि, इस customFields के उपभोक्ता के लिए किसी न किसी प्रकार से निपटने उतारने की जाएगी, लेकिन अगर साथ एक विशिष्ट फ़ील्ड का नाम जुड़े मूल्य प्रकार जाना जाता है ठीक होना चाहिए।

+0

मैं आपके पहले दृष्टिकोण से सहमत हूं और यही कारण है कि यह मेरा अपवॉट मिला लेकिन नीचे संस्करण - उस मामले में .. जेनेरिक का उपयोग क्यों नहीं करें? .. :) –

+0

आप सही हैं! मेरा मतलब केवल श्वेतसूची वाले प्रकारों के मामले में जोड़ना था, लेकिन जेनरिक के साथ भी आप ': कहां टी: [प्रकारों की अनुमति] 'के उपयोग से प्रतिबंधित हो सकते हैं। आपके अपवोट के लिए धन्यवाद :) –

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

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