मैंने उन्हें बहुत सारे तरीकों से इस्तेमाल करते हुए देखा है, और मुझे चिंता है कि मैं डिजाइन में एक पथ से नीचे जाने वाला हूं जो इस बेहतर नहीं होने पर अपरिवर्तनीय है। इसके अलावा, मैं .NET का उपयोग कर रहा हूं।
मैंने उन्हें बहुत सारे तरीकों से इस्तेमाल करते हुए देखा है, और मुझे चिंता है कि मैं डिजाइन में एक पथ से नीचे जाने वाला हूं जो इस बेहतर नहीं होने पर अपरिवर्तनीय है। इसके अलावा, मैं .NET का उपयोग कर रहा हूं।
जवाबों:
Collection<T>
चारों ओर एक अनुकूलन योग्य आवरण है IList<T>
। जबकि IList<T>
सील नहीं है, यह कोई अनुकूलन अंक प्रदान नहीं करता है। Collection<T>
डिफ़ॉल्ट IList<T>
तरीके मानक विधियों को सौंप दिए गए हैं , लेकिन आप जो चाहते हैं उसे करने के लिए आसानी से ओवरराइड किया जा सकता है। यह भी संभव है Collection<T>
कि मैं इलिस्ट के साथ ऐसा न कर सकूं कि मेरे अंदर की घटनाओं को तार-तार करना संभव है ।
संक्षेप में, इस तथ्य के बाद इसे बढ़ाना बहुत आसान है, जो संभावित रूप से बहुत कम रिफैक्टिंग का मतलब हो सकता है।
IList
, जो कुछ भी दिखता है IList<T>
, List<T>
आदि। संक्षेप में, आपको पता नहीं है कि क्या इसे कहा जाएगा। बहुरूपता इसे ठीक करता है।
ObservableCollection<T>
एक उदाहरण के रूप में जोड़ना चाह सकते हैं जहाँ परिवर्तनों के बारे में सूचित करने के लिए तरीकों को ओवरराइड किया जाता है।
C # में, वस्तुओं के एक बैग का प्रतिनिधित्व करने के लिए तीन अवधारणाएं हैं। बढ़ती सुविधाओं के क्रम में, वे हैं:
Enumerable का कोई आदेश नहीं है। आप सेट से आइटम नहीं जोड़ सकते या निकाल नहीं सकते हैं। आप सेट में वस्तुओं की एक गिनती भी नहीं प्राप्त कर सकते हैं। यह आपको सेट में प्रत्येक आइटम को एक के बाद एक एक्सेस करने देता है।
संग्रह एक परिवर्तनीय सेट है। आप सेट से वस्तुओं को जोड़ और हटा सकते हैं, आप सेट में वस्तुओं की गिनती भी प्राप्त कर सकते हैं। लेकिन अभी भी कोई आदेश नहीं है, और क्योंकि कोई आदेश नहीं है: सूचकांक द्वारा किसी आइटम तक पहुंचने का कोई तरीका नहीं है, न ही किसी तरह का कोई तरीका है।
सूची वस्तुओं का एक निर्धारित समूह है। आप सूची को सॉर्ट कर सकते हैं, इंडेक्स द्वारा एक्सेस आइटम, इंडेक्स द्वारा आइटम हटा सकते हैं।
वास्तव में, जब इन के लिए इंटरफेस को देखते हैं, तो वे एक दूसरे पर निर्माण करते हैं:
interface IEnumerable<T>
GetEnumeration<T>
interface ICollection<T> : IEnumerable<T>
Add
Remove
Clear
Count
interface IList<T> = ICollection<T>
Insert
IndexOf
RemoveAt
चर, या विधि पैरामीटर की घोषणा करते समय, आपको उपयोग करने का चयन करना चाहिए
वैचारिक रूप से आपको वस्तुओं के सेट के साथ करने की आवश्यकता है।
यदि आपको किसी सूची में प्रत्येक वस्तु के लिए कुछ करने में सक्षम होने की आवश्यकता है, तो आपको केवल आवश्यकता है IEnumerable
:
void SaveEveryUser(IEnumerable<User> users)
{
for User u in users
...
}
आप परवाह नहीं उपयोगकर्ता एक में रखा जाता है, तो है List<T>
, Collection<T>
, Array<T>
या कुछ और। आपको केवल IEnumerable<T>
इंटरफ़ेस की आवश्यकता है।
यदि आपको एक सेट में वस्तुओं को जोड़ने, हटाने या गिनने में सक्षम होने की आवश्यकता है, तो एक संग्रह का उपयोग करें :
ICollection<User> users = new Collection<User>();
users.Add(new User());
यदि आप एक क्रम के बारे में परवाह करते हैं, और आदेश को सही होने की आवश्यकता है, तो एक सूची का उपयोग करें :
IList<User> users = FetchUsers(db);
चार्ट के रूप में:
| Feature | IEnumerable<T> | ICollection<T> | IList<T> |
|------------------------|----------------|----------------|----------|
| Enumerating items | X | X | X |
| | | | |
| Adding items | | X | X |
| Removing items | | X | X |
| Count of items | | X | X |
| | | | |
| Accessing by index | | | X |
| Removing by indexx | | | X |
| Getting index of item | | | X |
List<T>
और Collection<T>
में System.Collections.Generic
दो वर्गों है कि इन इंटरफेस को लागू कर रहे हैं; लेकिन वे केवल वर्ग नहीं हैं:
ConcurrentBag<T>
वस्तुओं का एक ऑर्डर किया गया बैग है ( IEnumerable<T>
)LinkedList<T>
एक बैग है जहाँ आपको अनुक्रमणिका द्वारा वस्तुओं तक पहुँचने की अनुमति नहीं है ( ICollection
); लेकिन आप संग्रह से आइटम को मनमाने ढंग से जोड़ और हटा सकते हैंSynchronizedCollection<T>
एक ऑर्डर किए गए संग्रह में, जहां आप इंडेक्स द्वारा आइटम जोड़ / हटा सकते हैंतो आप आसानी से बदल सकते हैं:
IEnumerable<User> users = new SynchronizedCollection<User>();
SaveEveryUser(users);
आपके लिए आवश्यक अवधारणा चुनें , फिर मिलान वर्ग का उपयोग करें।
ICollection<T>
और करने के लिए बात कर रहा हूँ IList<T>
। विभिन्न ठोस कार्यान्वयन अलग तरह से व्यवहार कर सकते हैं। उदाहरण के लिए यदि आप List<T>
इसके IEnumerable<T>
इंटरफ़ेस के माध्यम से एक्सेस करते हैं , तो आपके पास सूची में आइटम जोड़ने, हटाने, सॉर्ट करने या गिनने का कोई तरीका नहीं है।
List<T>
एप्लिकेशन कोड के भीतर आंतरिक उपयोग के लिए अभिप्रेत है। आपको सार्वजनिक एपीआई लिखने से बचना चाहिए जो स्वीकार या वापसी करते हैं List<T>
(इसके बजाय सुपरक्लास या संग्रह इंटरफ़ेस का उपयोग करने पर विचार करें)।
Collection<T>
कस्टम संग्रह के लिए एक बेस क्लास परोसता है (हालाँकि इसे सीधे इस्तेमाल किया जा सकता है)।
Collection<T>
अपने कोड का उपयोग करने पर विचार करें जब तक List<T>
कि आपकी विशिष्ट विशेषताएं न हों ।
उपरोक्त केवल सिफारिशें हैं।
[से लिया गया: फ्रेमवर्क डिज़ाइन दिशानिर्देश, दूसरा संस्करण]
Dictionary<string, List<string>>
लिए रिटर्न के लिए उदाहरण के लिए List<string>
, ठीक है, क्योंकि शब्दकोश की स्थिति केवल उसकी सामग्री की बजाय सूचियों की पहचान को गुप्त करती है।
List<T>
एक बहुत ही सामान्य रूप से देखा जाने वाला कंटेनर है, क्योंकि यह बहुत ही बहुमुखी है (बहुत सारी आसान विधियों जैसे Sort
, Find
आदि) के साथ - लेकिन कोई विस्तार बिंदु नहीं है यदि आप किसी भी व्यवहार को ओवरराइड करना चाहते हैं (उदाहरण के लिए आइटम चेक करें)।
Collection<T>
किसी के आसपास एक रैपर है IList<T>
(डिफ़ॉल्ट करने के लिए List<T>
) - इसमें विस्तार बिंदु ( virtual
विधियां) हैं, लेकिन जैसे कई समर्थन विधियां नहीं हैं Find
। परोक्ष की वजह से, यह थोड़ा धीमा है List<T>
, लेकिन बहुत ज्यादा नहीं है।
LINQ के साथ, अतिरिक्त तरीकों में List<T>
कम महत्वपूर्ण हो, के बाद से LINQ करने वाली वस्तुओं वैसे भी उन्हें प्रदान करता है ... उदाहरण के लिए First(pred)
, OrderBy(...)
आदि
लिस्ट तेज है।
उदाहरण के लिए करें
private void button1_Click(object sender, EventArgs e)
{
Collection<long> c = new Collection<long>();
Stopwatch s = new Stopwatch();
s.Start();
for (long i = 0; i <= 10000000; i++)
{
c.Add(i);
}
s.Stop();
MessageBox.Show("collect " + s.ElapsedMilliseconds.ToString());
List<long> l = new List<long>();
Stopwatch s2 = new Stopwatch();
s2.Start();
for (long i = 0; i <= 10000000; i++)
{
l.Add(i);
}
s2.Stop();
MessageBox.Show("lis " + s2.ElapsedMilliseconds.ToString());
}
मेरी मशीन List<>
पर लगभग दोगुना तेज है।
संपादित करें
मैं समझ नहीं पा रहा हूं कि लोग इसे क्यों कम कर रहे हैं। मेरी कार्य मशीन और मेरे होम मशीन दोनों पर सूची <> कोड 80% तेज है।
सूची एक संग्रह का प्रतिनिधित्व करती है जहां वस्तुओं का क्रम महत्वपूर्ण है। यह भी एक सॉर्ट और खोज के तरीकों का समर्थन करता है। संग्रह एक अधिक सामान्य डेटा-संरचना है जो डेटा के बारे में कम धारणा बनाता है और इसे हेरफेर करने के लिए कम तरीकों का भी समर्थन करता है। यदि आप एक कस्टम डेटा संरचना को उजागर करना चाहते हैं, तो आपको संभवतः संग्रह का विस्तार करना चाहिए। यदि आपको डेटा-संरचना को उजागर करने वाले डेटा w / o में हेरफेर करने की आवश्यकता है, तो एक सूची संभवतः जाने का सबसे सुविधाजनक तरीका है।
यह उन ग्रेड स्कूल के सवालों में से एक है। टी का एक संग्रह सार की तरह है; एक डिफ़ॉल्ट कार्यान्वयन हो सकता है (मैं एक .net / c # आदमी नहीं हूं), लेकिन एक संग्रह में बुनियादी ऑपरेशन होंगे जैसे ऐड, रिमूव, इट्रेट, और इसी तरह।
टी की सूची से इन कार्यों के बारे में कुछ बारीकियों के बारे में पता चलता है: ऐड को निरंतर समय लेना चाहिए, तत्वों की संख्या के लिए आनुपातिक समय निकालना चाहिए, गेटफैस्ट कंसेंट टाइम होना चाहिए। सामान्य तौर पर, एक सूची संग्रह का एक प्रकार है, लेकिन एक संग्रह आवश्यक रूप से एक प्रकार की सूची नहीं है।
हंसेलमैन बोलता है : " Collection<T>
एक सूची की तरह दिखता है, और इसमें एक List<T>
आंतरिक रूप से भी है । हर एक विधि आंतरिक को दर्शाता है List<T>
। इसमें एक संरक्षित संपत्ति शामिल है जो उजागर करती है List<T>
।"
संपादित करें: Collection<T>
System.Generic.Collections .NET 3.5 में मौजूद नहीं है। यदि आप .NET 2.0 से 3.5 पर माइग्रेट करते हैं, तो यदि आप बहुत अधिक उपयोग कर रहे हैं, तो आपको कुछ कोड बदलने की आवश्यकता होगीCollection<T>
वस्तुओं हैं, जब तक कि मैं कुछ स्पष्ट याद नहीं कर रहा हूं ...
EDIT 2: Collection<T>
अब .NET 3.5 में System.Collections.ObjectModel नाम स्थान पर है। मदद फ़ाइल यह कहती है:
"System.Collections.ObjectModel नामस्थान में ऐसी कक्षाएं होती हैं जिन्हें पुन: प्रयोज्य लाइब्रेरी के ऑब्जेक्ट मॉडल में संग्रह के रूप में उपयोग किया जा सकता है। इन वर्गों का उपयोग तब करें जब गुण या विधियाँ संग्रह लौटा दें।"
इन सभी इंटरफेस से विरासत मिलती है IEnumerable
, जिसे आपको सुनिश्चित करना चाहिए कि आप समझ सकें। वह इंटरफ़ेस मूल रूप से आपको फ़ॉर्च स्टेटमेंट (C # में) क्लास का उपयोग करने देता है।
ICollection
आपके द्वारा सूचीबद्ध इंटरफेस का सबसे बुनियादी है। यह एक गूढ़ इंटरफ़ेस है जो समर्थन करता है Count
और इसके बारे में है।IList
वह सब कुछ है जो ICollection
वस्तुओं को जोड़ने और हटाने का समर्थन करता है, सूचकांक द्वारा वस्तुओं को पुनः प्राप्त करना, आदि। यह "वस्तुओं की सूचियों" के लिए सबसे अधिक उपयोग किया जाने वाला इंटरफ़ेस है, जो कि मुझे पता है कि अस्पष्ट है।IQueryable
एक गणनीय इंटरफ़ेस है जो LINQ का समर्थन करता है। आप हमेशा IQueryable
एक IList से बना सकते हैं और LINQ का उपयोग ऑब्जेक्ट्स के लिए कर सकते हैं, लेकिन आप IQueryable
LINQ में SQL स्टेटमेंट्स में SQL स्टेटमेंट्स और एंटिटीज के लिए आस्थगित निष्पादन के लिए भी उपयोग किया जाता है।IDictionary
इस अर्थ में एक अलग जानवर है कि यह मूल्यों के लिए अद्वितीय कुंजी का मानचित्रण है। यह भी उल्लेखनीय है कि आप कुंजी / मान युग्मों की गणना कर सकते हैं, लेकिन अन्यथा यह आपके द्वारा सूचीबद्ध अन्य लोगों की तुलना में एक अलग उद्देश्य प्रदान करता है।MSDN के अनुसार, सूची (T की) .dd "O (n) ऑपरेशन" (जब "क्षमता" पार हो जाती है), जबकि Collection (T का) .Add हमेशा "O (1) ऑपरेशन" होता है। यह समझ में आता है अगर सूची एक ऐरे और संग्रहित लिंक का उपयोग करके कार्यान्वित की जाती है। हालाँकि, अगर ऐसा होता, तो एक संग्रह (T) की अपेक्षा करता। यह "O (n) ऑपरेशन" होगा। लेकिन - यह है - नहीं !? संग्रह (टी का)। यह "ओ (1) ऑपरेशन है" जैसे सूची (टी का)। इटेम।
उस के शीर्ष पर, "tuinstoel" का "Dec 29 '08 22:31 पर" पोस्ट से ऊपर का दावा है कि गति परीक्षण दिखाता है सूची (T का)। संग्रह (T का) की तुलना में तेज़ होना है। ठीक है, जो मैंने पुन: प्रस्तुत किया है। लंबे और स्ट्रिंग का। हालाँकि मैं केवल ~ 33% तेजी से बनाम उसका दावा किया 80%, MSDN के अनुसार, यह विपरीत और "कई बार" होना चाहिए था !?
दोनों एक ही इंटरफेस लागू करते हैं, इसलिए वे एक ही तरह से व्यवहार करेंगे। शायद उन्हें आंतरिक रूप से अलग तरीके से लागू किया जाता है, लेकिन इसका परीक्षण करना होगा।
केवल वास्तविक अंतर जो मैं देख रहा हूं वे नामस्थान और तथ्य हैं Collection<T>
, जिनके साथ चिह्नित है ComVisibleAttribute(false)
, इसलिए COM कोड इसका उपयोग नहीं कर सकता है।
अन्य asnwers के अलावा, मैंने सामान्य सूची और संग्रह क्षमताओं का त्वरित अवलोकन संकलित किया है। संग्रह सूची का सीमित सबसेट है:
* = वर्तमान
ओ = आंशिक रूप से मौजूद है
संपत्ति / विधि संग्रह < T > सूची < T > --------------------------------------- -------
Add() * *
AddRange() *
AsReadOnly() *
BinarySearch() *
Capacity *
Clear() * *
Contains() * *
ConvertAll() *
CopyTo() o *
Count * *
Equals() * *
Exists() *
Find() *
FindAll() *
FindIndex() *
FindLast() *
FindLastIndex() *
ForEach() *
GetEnumerator() * *
GetHashCode() * *
GetRange() *
GetType() * *
IndexOf() o *
Insert() * *
InsertRange() *
Item() * *
LastIndexOf() *
New() o *
ReferenceEquals() * *
Remove() * *
RemoveAll() *
RemoveAt() * *
RemoveRange() *
Reverse() *
Sort() *
ToArray() *
ToString() * *
TrimExcess() *
TrueForAll() *