MyClass[] array;
List<MyClass> list;
जब एक दूसरे पर बेहतर होता है तो क्या परिदृश्य होते हैं? और क्यों?
MyClass[] array;
List<MyClass> list;
जब एक दूसरे पर बेहतर होता है तो क्या परिदृश्य होते हैं? और क्यों?
जवाबों:
यह वास्तव में दुर्लभ है, कि आप एक सरणी का उपयोग करना चाहेंगे। निश्चित रूप से List<T>
किसी भी समय आप डेटा जोड़ना / निकालना चाहते हैं, क्योंकि सरणियों का आकार बदलना महंगा है। यदि आप जानते हैं कि डेटा निश्चित लंबाई है, और आप किसी बहुत विशिष्ट कारण (बेंचमार्किंग के बाद) के लिए माइक्रो-ऑप्टिमाइज़ करना चाहते हैं , तो एक सरणी उपयोगी हो सकती है।
List<T>
एक सरणी की तुलना में बहुत अधिक कार्यक्षमता प्रदान करता है (हालांकि LINQ इसे थोड़ा बढ़ाता है), और लगभग हमेशा सही विकल्प होता है। params
तर्कों को छोड़कर , बिल्कुल। ;-p
एक काउंटर के रूप में - List<T>
एक आयामी है; जहाँ-जहाँ आपके पास आयताकार (आदि) सरणियाँ होती हैं जैसे int[,]
या string[,,]
- लेकिन ऑब्जेक्ट मॉडल में इस तरह के डेटा (यदि आपको ज़रूरत है) मॉडलिंग के अन्य तरीके हैं।
यह सभी देखें:
उन्होंने कहा, मैं अपने प्रोटोबॉफ़-नेट में सरणियों का बहुत उपयोग करता हूं परियोजना ; पूरी तरह से प्रदर्शन के लिए:
byte[]
एन्कोडिंग के लिए बहुत आवश्यक है;byte[]
बफर का करता हूं जिसे मैं अंतर्निहित स्ट्रीम (और वीवी) पर भेजने से पहले भरता हूं; BufferedStream
आदि से तेज ;Foo[]
बजाय इसकेList<Foo>
) , क्योंकि आकार एक बार बनाया गया है, और बहुत तेज़ होने की आवश्यकता है।लेकिन यह निश्चित रूप से एक अपवाद है; सामान्य लाइन-ऑफ-बिजनेस प्रोसेसिंग के लिए, List<T>
हर बार एक जीत।
वास्तव में सिर्फ एक लिंक जोड़ने के लिए जवाब दे रहा हूं, जो मुझे आश्चर्यचकित करता है कि अभी तक इसका उल्लेख नहीं किया गया है: एरिक के लिपर्ट के ब्लॉग पर "एर्र को " बहुत हानिकारक माना जाता है। "
आप शीर्षक से न्याय कर सकते हैं कि यह जहाँ भी व्यावहारिक है, संग्रह का उपयोग करने का सुझाव दे रहा है - लेकिन जैसा कि मार्क सही बताता है, ऐसे बहुत सारे स्थान हैं जहाँ एक सरणी वास्तव में एकमात्र व्यावहारिक समाधान है।
अनुशंसा करते हुए अन्य उत्तरों के बावजूद List<T>
, आप संभालते समय सरणियों का उपयोग करना चाहेंगे:
List<T>
एक बाइट सरणी के बजाय यहां उपयोग करने के खिलाफ क्या बोलता है ?
जब तक आप वास्तव में प्रदर्शन से चिंतित हैं, और इससे मेरा मतलब है, "आप C ++ के बजाय .Net का उपयोग क्यों कर रहे हैं?" आपको सूची <> के साथ रहना चाहिए। इसे बनाए रखना आसान है और आपके लिए पर्दे के पीछे एक सरणी को आकार देने के सभी गंदे काम करता है। (यदि आवश्यक हो, तो सूची <> सरणी आकारों को चुनने के बारे में बहुत स्मार्ट है, इसलिए आमतौर पर इसकी आवश्यकता नहीं होती है।)
Arrays चाहिए सूची को वरीयता में इस्तेमाल किया जा जब संग्रह खुद की अचल ग्राहक और सेवा प्रदाता कोड (जरूरी नहीं संग्रह के आइटमों में से अचल स्थिति) और जब IEnumerable उपयुक्त नहीं है के बीच अनुबंध का हिस्सा है।
उदाहरण के लिए,
var str = "This is a string";
var strChars = str.ToCharArray(); // returns array
यह स्पष्ट है कि "strChars" का संशोधन मूल "str" ऑब्जेक्ट को म्यूट नहीं करेगा, भले ही "str" के अंतर्निहित प्रकार का गैर-कार्यान्वयन कार्यान्वयन-स्तरीय ज्ञान हो।
लेकिन मान लीजिए कि
var str = "This is a string";
var strChars = str.ToCharList(); // returns List<char>
strChars.Insert(0, 'X');
इस मामले में, यह केवल उस कोड-स्निपेट से स्पष्ट नहीं है, यदि सम्मिलित विधि मूल "str" ऑब्जेक्ट को म्यूट नहीं करेगी या नहीं करेगी। इसे उस निर्धारण को करने के लिए स्ट्रिंग के कार्यान्वयन स्तर के ज्ञान की आवश्यकता होती है, जो अनुबंध दृष्टिकोण द्वारा डिजाइन को तोड़ता है। स्ट्रिंग के मामले में, यह कोई बड़ी बात नहीं है, लेकिन लगभग हर दूसरे मामले में यह एक बड़ी बात हो सकती है। सूची को केवल-पढ़ने के लिए सेट करना मदद करता है, लेकिन रन-टाइम त्रुटियों के परिणामस्वरूप, संकलन-समय नहीं।
To
, एक ऐसी वस्तु बनाने जा रही है, strChars as char[]
जिसमें मूल उदाहरण को संशोधित करने की कोई क्षमता नहीं है, जिसके विरोध में यदि मान्य है तो आप मूल वस्तु को संशोधित करने में सक्षम हैं।
str
आंतरिक रूप से एक सरणी का उपयोग करता है और ToCharArray
इस सरणी का संदर्भ देता है, तो ग्राहक str
उस सरणी के तत्वों को बदलकर म्यूट कर सकता है , भले ही आकार निर्धारित हो। फिर भी आप लिखते हैं 'यह स्पष्ट है कि "strChars" का संशोधन मूल "str" ऑब्जेक्ट को म्यूट नहीं करेगा। " मुझे यहां क्या समझ नहीं आ रहा है? मैं जो भी देख सकता हूं, किसी भी मामले में क्लाइंट के पास आंतरिक प्रतिनिधित्व तक पहुंच हो सकती है और, प्रकार की परवाह किए बिना, यह कुछ प्रकार के उत्परिवर्तन की अनुमति देगा।
तो मुझे पता है कि उनकी संख्या कितनी तत्वों मैं जरूरत के लिए जा रहा हूँ, मैं 5 तत्वों और केवल जरूरत है कहते हैं कि कभी 5 तत्वों तो मैं एक सरणी का उपयोग करें। अन्यथा मैं सिर्फ एक सूची <T> का उपयोग करता हूं।
ज्यादातर बार, एक List
पर्याप्त का उपयोग करना होगा। एक List
अपने डेटा को संभालने के लिए एक आंतरिक सरणी का उपयोग करता है, और List
अपनी वर्तमान क्षमता की तुलना में अधिक तत्वों को जोड़ने पर स्वचालित रूप से सरणी का आकार बदल देता है, जो सरणी की तुलना में उपयोग करना अधिक आसान बनाता है, जहां आपको पहले से क्षमता जानने की आवश्यकता होती है।
Http:// #ddn.microsoft.com/en-us/library/ms379570(v=vs.80) .aspx #datastructures20_1_topic5 C # या सिर्फ डिकंपाइल में सूचियों के बारे में अधिक जानकारी के लिए देखें System.Collections.Generic.List<T>
।
यदि आपको बहुआयामी डेटा की आवश्यकता है (उदाहरण के लिए मैट्रिक्स या ग्राफिक्स प्रोग्रामिंग का उपयोग करके), तो आप शायद array
इसके बजाय जाएंगे ।
हमेशा की तरह, यदि स्मृति या प्रदर्शन एक मुद्दा है, तो इसे मापें! अन्यथा आप कोड के बारे में गलत धारणा बना सकते हैं।
बनाम बनाम सूची एक क्लासिक रखरखाव बनाम प्रदर्शन समस्या है। अंगूठे का नियम जो लगभग सभी डेवलपर्स का पालन करते हैं, आपको दोनों के लिए शूट करना चाहिए, लेकिन जब वे संघर्ष में आते हैं, तो प्रदर्शन पर स्थिरता का चयन करें। उस नियम का अपवाद तब है जब प्रदर्शन पहले से ही एक मुद्दा साबित हुआ है। यदि आप इस सिद्धांत को Arrays Vs. सूचियाँ, तो आपको जो मिलता है वह यह है:
जब तक आप प्रदर्शन की समस्याओं से नहीं टकराते हैं, तब तक दृढ़ता से टाइप की गई सूचियों का उपयोग करें। यदि आप प्रदर्शन समस्या से जूझते हैं, तो यह निर्णय लें कि क्या सरणियों को छोड़ना आपके समाधान को प्रदर्शन से अधिक लाभ देगा, क्योंकि यह रखरखाव के मामले में आपके समाधान के लिए एक बाधा होगी।
एक और स्थिति का अभी तक उल्लेख नहीं किया गया है जब किसी के पास बड़ी संख्या में आइटम होंगे, जिनमें से प्रत्येक में संबंधित-लेकिन-स्वतंत्र चर का एक निश्चित गुच्छा होता है (जैसे एक बिंदु के निर्देशांक, या एक 3 डी त्रिकोण के कोने)। उजागर-क्षेत्र संरचनाओं की एक सरणी अपने तत्वों को "जगह में" कुशलता से संशोधित करने की अनुमति देगी - ऐसा कुछ जो किसी अन्य संग्रह प्रकार के साथ संभव नहीं है। क्योंकि संरचनाओं की एक सरणी रैम में अपने तत्वों को लगातार रखती है, इसलिए सरणी तत्वों तक अनुक्रमिक पहुंच बहुत तेज हो सकती है। ऐसी स्थितियों में जहां कोड को एक सरणी से कई अनुक्रमिक पास बनाने की आवश्यकता होगी, संरचनाओं का एक सरणी 2: 1 के कारक द्वारा एक सरणी या वर्ग ऑब्जेक्ट संदर्भ के अन्य संग्रह को बेहतर बना सकता है; आगे की,
हालाँकि सरणियाँ पुनरुत्थान योग्य नहीं हैं, फिर भी कोड सरणी को संदर्भ के साथ उपयोग करने वाले तत्वों की संख्या के साथ स्टोर करना मुश्किल नहीं है, और आवश्यकता के अनुसार सरणी को बड़े से बदलें। वैकल्पिक रूप से, कोई भी आसानी से एक प्रकार के लिए कोड लिख सकता है, जो List<T>
अपने बैकिंग स्टोर के संपर्क में है, लेकिन इस तरह से MyPoints.Add(nextPoint);
या तो कहने की अनुमति देता है MyPoints.Items[23].X += 5;
। ध्यान दें कि बाद में एक अपवाद नहीं फेंकना चाहिए यदि कोड सूची के अंत से परे तक पहुंचने की कोशिश करता है, लेकिन उपयोग अन्यथा वैचारिक रूप से काफी समान होगा List<T>
।
Point[] arr;
, कोड के लिए यह कहना संभव है, जैसे arr[3].x+=q;
। उदाहरण के लिए List<Point> list
, इसके बजाय यह कहना आवश्यक होगा Point temp=list[3]; temp.x+=q; list[3]=temp;
। यह List<T>
एक विधि होती तो मददगार होती Update<TP>(int index, ActionByRefRef<T,TP> proc, ref TP params)
। और compilers बदल सकता है list[3].x+=q;
में {list.Update(3, (ref int value, ref int param)=>value+=param, ref q);
लेकिन ऐसी कोई सुविधा मौजूद है।
list[0].X += 3;
सूची के पहले तत्व के 3 से X गुण जोड़ देगा। और list
एक है List<Point>
और Point
एक्स और वाई गुणों के साथ एक वर्ग है
.NET में सूचियाँ सरणियों पर आवरण होती हैं, और आंतरिक रूप से एक सरणी का उपयोग करती हैं। सूचियों पर संचालन की समय जटिलता सरणियों के साथ ही होगी, हालांकि सूचियों के उपयोग की सभी अतिरिक्त कार्यक्षमता / आसानी (जैसे कि स्वचालित आकार बदलना और सूची वर्ग के साथ आने वाले तरीके) के साथ थोड़ा अधिक ओवरहेड है। बहुत अधिक, मैं सभी मामलों में सूचियों का उपयोग करने की सिफारिश करूंगा जब तक कि ऐसा करने के लिए एक सम्मोहक कारण नहीं है, जैसे कि यदि आपको अत्यंत अनुकूलित कोड लिखने की आवश्यकता है, या अन्य कोड के साथ काम कर रहे हैं जो सरणियों के आसपास बनाया गया है।
प्रत्येक डेटा प्रकार की सुविधाओं की तुलना के माध्यम से जाने के बजाय, मुझे लगता है कि सबसे व्यावहारिक जवाब है "अंतर शायद इतना महत्वपूर्ण नहीं है कि आपको क्या हासिल करने की आवश्यकता है, खासकर जब से वे दोनों लागू होते हैं IEnumerable
, इसलिए लोकप्रिय सम्मेलन का पालन करें और एक का उपयोग करें List
जब तक आपके पास कोई कारण नहीं है, तब तक आप शायद ए पर एक सरणी का उपयोग करने के लिए अपना कारण बताएंगेList
। "
प्रबंधित कोड के अधिकांश समय आप माइक्रो-ऑप्टिमाइज़ेशन के बारे में चिंता करने से अधिक से अधिक आसानी से काम करने के लिए संग्रह का पक्ष लेना चाहते हैं।
वे अलोकप्रिय हो सकते हैं, लेकिन मैं खेल परियोजनाओं में अर्रे का प्रशंसक हूं। - कुछ मामलों में धमनियों की गति महत्वपूर्ण हो सकती है, एक एरे पर फोरच में काफी कम ओवरहेड होता है यदि आप प्रति तत्व बहुत कुछ नहीं कर रहे हैं - सहायक कार्यों के साथ जोड़ना और निकालना इतना कठिन नहीं है - इसका धीमा, लेकिन उन मामलों में जहां आप केवल एक बार निर्माण करते हैं इससे कोई फर्क नहीं पड़ता - ज्यादातर मामलों में, कम अतिरिक्त मेमोरी बर्बाद हो जाती है (केवल संरचना के अर्रे के साथ वास्तव में महत्वपूर्ण) - थोड़ा कम कचरा और संकेत और पॉइंटर का पीछा करना
यह कहा जा रहा है, मैं अभ्यास में अर्रे की तुलना में कहीं अधिक बार सूची का उपयोग करता हूं, लेकिन उनके पास प्रत्येक जगह है।
यह अच्छा होगा यदि सूची जहां एक प्रकार में निर्मित हो ताकि वे रैपर और एन्यूमरेशन ओवरहेड को अनुकूलित कर सकें।
एक सूची बनाना एक सरणी से आसान है। सरणियों के लिए, आपको डेटा की सही लंबाई जानने की आवश्यकता है, लेकिन सूचियों के लिए, डेटा का आकार कोई भी हो सकता है। और, आप एक सूची को एक सरणी में बदल सकते हैं।
List<URLDTO> urls = new List<URLDTO>();
urls.Add(new URLDTO() {
key = "wiki",
url = "https://...",
});
urls.Add(new URLDTO()
{
key = "url",
url = "http://...",
});
urls.Add(new URLDTO()
{
key = "dir",
url = "https://...",
});
// convert a list into an array: URLDTO[]
return urls.ToArray();
चूंकि कोई भी उल्लेख नहीं करता है: सी # में, एक सरणी एक सूची है। MyClass[]
और List<MyClass>
दोनों लागू होते हैं IList<MyClass>
। (जैसे void Foo(IList<int> foo)
कहा जा सकता है Foo(new[] { 1, 2, 3 })
या Foo(new List<int> { 1, 2, 3 })
)
इसलिए, यदि आप एक ऐसा तरीका लिख रहे हैं List<MyClass>
जो तर्क के रूप में स्वीकार करता है , लेकिन केवल सुविधाओं के सबसेट का उपयोग करता है, तो आप IList<MyClass>
कॉल करने वालों की सुविधा के लिए घोषित करना चाह सकते हैं ।
विवरण:
List
, यह केवल IList
इंटरफ़ेस को लागू करता है।
यह पूरी तरह से संदर्भों पर निर्भर करता है जिसमें डेटा संरचना की आवश्यकता होती है। उदाहरण के लिए, यदि आप सूची का उपयोग करके अन्य कार्यों या सेवाओं द्वारा उपयोग किए जाने वाले आइटम बना रहे हैं, तो इसे पूरा करने का सही तरीका है।
अब यदि आपके पास मदों की एक सूची है और आप उन्हें प्रदर्शित करना चाहते हैं, तो वेब पेज सरणी पर कंटेनर को उपयोग करने की आवश्यकता है।
IEnumerable<T>
- फिर मैं उन्हें बफर करने के बजाय वस्तुओं को स्ट्रीम कर सकता हूं।
यह मौके पर कास्टिंग करने की क्षमता के बारे में ध्यान देने योग्य है।
interface IWork { }
class Foo : IWork { }
void Test( )
{
List<Foo> bb = new List<Foo>( );
// Error: CS0029 Cannot implicitly convert type 'System.Collections.Generic.List<Foo>' to 'System.Collections.Generic.List<IWork>'
List<IWork> cc = bb;
Foo[] bbb = new Foo[4];
// Fine
IWork[] ccc = bbb;
}
इसलिए एरियर रिटर्न प्रकार या कार्यों के लिए तर्क में उपयोग किए जाने पर थोड़ा अधिक लचीलापन प्रदान करता है।
IWork[] GetAllWorks( )
{
List<Foo> fooWorks = new List<Foo>( );
return fooWorks.ToArray( ); // Fine
}
void ExecuteWorks( IWork[] works ) { } // Also accept Foo[]