2015-04-12 15 views
6

के लिए हर *Collection (HtmlNodeCollection, TreeNodeCollection, CookieCollection आदि) वर्ग उदाहरण है कि मैं एक तरीका है जिसके केवल एक सरणी या सूची को स्वीकार करता है को पास किए जाने (एक विधि है कि उदाहरण के लिए TreeView में एक TreeNodeCollection स्वीकार करता है नहीं करना चाहिए था?) मेरे पास है इस तरह की एक एक्सटेंशन-विधि लिखने के लिए:संग्रह को संग्रह या सूची में कनवर्ट करने का त्वरित तरीका?

public static TreeNode[] ToArray(this TreeNodeCollection nodes) 
     { 
      TreeNode[] arr = new TreeNode[nodes.Count]; 
      nodes.CopyTo(arr, 0); 
      return arr; 
     } 

या पूरे संग्रह एक उत्पादन-सूची में आइटम डाले और फिर एक सरणी के लिए उत्पादन-सूची परिवर्तित करने से अधिक पाश:

public static TreeNode[] ToArray(this TreeNodeCollection nodes) 
     { 
     var output = new List<TreeNode>(); 
      foreach (TreeNode node in nodes) 
       output.Nodes(node); 
      return output.ToArray(); 
} 

तो, मेरा सवाल है: मुझे अक्सर इस एक्सटेंशन-विधियों की आवश्यकता है। यदि सूची बड़ी है, तो आमतौर पर यह बहुत सारी मेमोरी आवंटित कर सकती है। मुझे इस *Collection कक्षाओं द्वारा उपयोग की जाने वाली आंतरिक सरणी में केवल एक संदर्भ (प्रतिलिपि नहीं) क्यों नहीं मिल सकता है ताकि मुझे उस एक्सटेंशन का उपयोग करने और इस स्मृति आवंटन को प्रतिबिंबित करने की आवश्यकता न हो? या यहां तक ​​कि ToArray() विधि प्रदान करें। हमें उस अंतिम मामले में उपयोग किए जाने वाले आंतरिक कार्यान्वयन या सरणी को जानने की आवश्यकता नहीं है।

+5

'मुझे एक विधि को पास करने की आवश्यकता है जो केवल एक सरणी या सूची स्वीकार करता है' क्यों नहीं 'IENumerable '? आप आसानी से 'treeNodeCollection.Cast ()' पूर्व के लिए पास कर सकते हैं। – EZI

+3

'IENumerable ' का उपयोग करें। यदि आपको सरणी की आवश्यकता है, तो 'संग्रह' का उपयोग करें। कैस्ट ()। टोएरे() 'और अपने एक्सटेंशन विधियों से पूरी तरह से छुटकारा पाएं। –

+0

'कैस्ट <>() 'वास्तव में अच्छा ... क्या संग्रह है। कैस्ट ()। टोएएरे()' मेरे 'से अलग है। टोएएरे()' एक्सटेंशन (तथ्य यह है कि यह मूल रूप से मूल है)? – Jack

उत्तर

10

कारण यह है कि सभी बीसीएल संग्रह वर्ग अपनी आंतरिक सरणी को छुपाते हैं, "एपीआई अच्छीता" के कारणों के लिए है। यदि आंतरिक वृद्धि या सिकुड़ने की आवश्यकता होती है तो आंतरिक सरणी बदल सकती है। फिर, किसी भी उपयोगकर्ता कोड जिसमें पुरानी सरणी का संदर्भ है, भ्रमित हो सकता है। साथ ही, उपयोगकर्ता कोड एरे इंडेक्स तक पहुंच सकता है जो संग्रह पर पहुंच के लिए अमान्य हैं। यदि आपके पास Capacity = 16 && Count == 10 के साथ है और फिर आप इंडेक्स 15 पर आंतरिक सरणी तक पहुंच सकते हैं, जो सूची सामान्य रूप से अनुमति नहीं देगी।

ये समस्याएं API को उपयोग करने में कठोर बनाती हैं। वे समर्थन टिकट और स्टैक ओवरफ़्लो प्रश्नों का कारण बनते हैं।

अपने मौजूदा कोड हटाएँ और साथ बदलें:

TreeNodeCollection nodes; 
var myArray = nodes.Cast<TreeNode>().ToArray(); 

आप एक विस्तार विधि में इस कर सकते हैं यदि आप उस के लिए की जरूरत महसूस करते हैं। IEnumerable (कोई जेनेरिक नहीं) के रूप में पैरामीटर टाइप करें। यह मेरे लिए एक रहस्य है कि बीसीएल में मौजूदा संग्रह को IEnumerable<T> लागू करने के लिए अपग्रेड नहीं किया गया है। यही कारण है कि आपको Case की आवश्यकता है। I just created a User Voice item for this.

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