2010-03-19 25 views
8

मेरी वर्तमान परियोजना में डेटा संरचनाओं में से एक के लिए आवश्यक है कि मैं विभिन्न प्रकारों (स्ट्रिंग, int, float, आदि) की सूचियों को संग्रहित करता हूं। मुझे यह जानने के बिना गतिशील रूप से किसी भी सूची को स्टोर करने में सक्षम होना चाहिए कि वे किस प्रकार के होंगे।विभिन्न प्रकार की सूचियों की सूची

मैंने प्रत्येक सूची को object के रूप में संग्रहीत करने का प्रयास किया, लेकिन मैं उचित प्रकार में वापस डालने की कोशिश करने में समस्याओं में भाग गया (यह सब कुछ List<String> के रूप में पहचान रहा था)।

उदाहरण के लिए:

List<object> myLists = new List<object>(); 

public static void Main(string args[]) 
{ 
    // Create some lists... 

    // Populate the lists... 

    // Add the lists to myLists... 

    for (int i = 0; i < myLists.Count; i++) 
    { 
     Console.WriteLine("{0} elements in list {1}", GetNumElements(i), i); 
    } 
} 

public int GetNumElements(int index) 
{ 
    object o = myLists[index]; 

    if (o is List<int>) 
     return (o as List<int>).Count; 

    if (o is List<String>)     // <-- Always true!? 
     return (o as List<String>).Count; // <-- Returning 0 for non-String Lists 

    return -1; 
} 

Am मैं गलत तरीके से कुछ कर रही? क्या विभिन्न प्रकार की सूचियों की सूची को स्टोर करने का कोई बेहतर तरीका है, या यह निर्धारित करने का एक बेहतर तरीका है कि कुछ निश्चित प्रकार की सूची है या नहीं?

+0

क्या आप एक न्यूनतम लेकिन पूरा प्रोग्राम पोस्ट कर सकते हैं जो आपकी समस्या का प्रदर्शन करता है? – dtb

उत्तर

10

टाइप List<T> गैर-जेनेरिक इंटरफ़ेस IList से प्राप्त होता है। चूंकि myList प्रकार के सभी मान List<T> के बाध्य हैं, आप उन्हें गैर-जेनेरिक IList के रूप में उपयोग कर सकते हैं। तो अगर आप उपयोग कर सकते हैं कि बहुत अपने तर्क सरल करने के लिए

public int GetNumElements(int index) { 
    object o = myLists[index]; 
    var l = o as IList; 
    return l.Count; 
} 

या वैकल्पिक रूप से के बाद से आप जानते हैं कि myList में संग्रहीत सभी मान, List<T> के लिए बाध्य संस्करण होगा object के बजाय प्रकार के रूप में IList का उपयोग करें।

List<IList> myLists = new List<IList>(); 
... 
public int GetNumElements(int index) { 
    return myList[index].Count; 
} 
+0

यह तब तक काम करता है जब तक मुझे सूचियों में कोई हेरफेर नहीं करना पड़ेगा, या जब मुझे मास्टर सूची में डालने के बाद सूची से कोई तत्व पुनर्प्राप्त करना होगा। क्या यह कहने का कोई आसान तरीका है कि 'IList' टाइप करें? – themarshal

+0

@themarshal वास्तव में नहीं। वास्तव में जांचने का एकमात्र तरीका समर्थित प्रकारों पर डालने के लिए 'as' ऑपरेटर का उपयोग करना है और उन्हें – JaredPar

+0

में हेरफेर करना है, अंत में मैंने सूची के प्रकार को ट्रैक करने के तरीके को ट्रैक करने के लिए एक तरीका निकाला।एक स्ट्रिंग सूची के रूप में पढ़ा जाने वाला सब कुछ इसलिए था क्योंकि जब मैं प्रकार के आधार पर सूचियां बना रहा था, तो "इंटीजर" प्रकार गलती से एक सूची उत्पन्न कर रहा था। ऊप्स! – themarshal

2

मुझे एहसास है कि यह एक पुराना है, लेकिन .NET 4 ने हमें इसके चारों ओर एक और तरीका दिया। क्या होगा यदि आप एक सूची चाहते थे जहां एक्स एक और सूची है, और y कोई भी प्रकार है?

दूसरे शब्दों में, एक सूची> आप ऑब्जेक्ट का प्रयास कर सकते हैं, लेकिन फिर आप हमेशा के रूप में इसके मूल प्रकार पर कुछ वापस डालने की कोशिश कर रहे हैं।

तो, यह एक दुर्लभ परिदृश्य है जहां नए गतिशील डेटा प्रकार का उपयोग किया जा सकता है। बेशक, यह आपको प्रकार की सुरक्षा को तोड़ने की इजाजत देता है, लेकिन इस मामले में, क्योंकि हम हमेशा किसी प्रकार की सूची से निपटने जा रहे हैं, यह कहना उचित है कि इसमें "काउंटर" संपत्ति होगी।

तो कुछ की तरह:

var myMainList = new List<List<dynamic>>(); 
var myInnerList1 = new List<string> { "A", "B", "C" }; 
var myInnerList2 = new List<int> { 1, 2, 3, 4, 5 }; 
myMainList.Add(myInnerList1); 
myMainList.Add(myInnerList2); 

// when we come to try and read the number of values in the list.. 
Console.WriteLine("inner list 1 : {0}", myMainList[0].Count); 
Console.WriteLine("inner list 2 : {0}", myMainList[1].Count); 

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

+0

आपका कोड संकलित भी नहीं करता है! – Arvand

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