मैं C # में एक सरणी की तरह सूची को क्यों आरंभ कर सकता हूं?


131

आज मुझे यह जानकर आश्चर्य हुआ कि C # में मैं कर सकता हूं:

List<int> a = new List<int> { 1, 2, 3 };

मैं ऐसा क्यों कर सकता हूं? कंस्ट्रक्टर को क्या कहा जाता है? मैं अपनी कक्षाओं के साथ यह कैसे कर सकता हूं? मुझे पता है कि यह arrays को इनिशियलाइज़ करने का तरीका है लेकिन arrays लैंग्वेज आइटम हैं और लिस्ट सरल ऑब्जेक्ट हैं ...


1
यह सवाल मदद का हो सकता है: stackoverflow.com/questions/1744967/…
बॉब कॉफ़मैन

10
बहुत बढ़िया हुह? आप शब्दकोशों को आरंभ करने के लिए समान कोड भी कर सकते हैं:{ { "key1", "value1"}, { "key2", "value2"} }
danludwig

एक अन्य दृष्टिकोण से यह सारणी जैसे आरंभीकरण सिंटैक्स हमें एक अनुस्मारक देता है कि अंतर्निहित डेटा प्रकार List<int>वास्तव में केवल एक सरणी है। मुझे इस तथ्य के लिए सी # टीम से नफरत है कि वे इसका नाम नहीं देते हैं ArrayList<T>जो इतना स्पष्ट और स्वाभाविक लगता है।
आरबीटी

जवाबों:


183

यह .NET में संग्रह आरम्भिक सिंटैक्स का हिस्सा है। इस सिंटैक्स का उपयोग आप किसी भी संग्रह पर कर सकते हैं जब तक आप इसे बनाते हैं:

  • यह लागू होता है IEnumerable(अधिमानतः IEnumerable<T>)

  • इसका नाम विधि है Add(...)

क्या होता है डिफॉल्ट कंस्ट्रक्टर कहा जाता है, और फिर Add(...)इनिशियलाइज़र के प्रत्येक सदस्य के लिए कहा जाता है।

इस प्रकार, ये दोनों ब्लॉक लगभग समान हैं:

List<int> a = new List<int> { 1, 2, 3 };

तथा

List<int> temp = new List<int>();
temp.Add(1);
temp.Add(2);
temp.Add(3);
List<int> a = temp;

आप चाहें तो एक वैकल्पिक निर्माणकर्ता को बुला सकते हैं, उदाहरण के लिए List<T>, बढ़ते समय आदि को रोकने के लिए, उदाहरण के लिए :

// Notice, calls the List constructor that takes an int arg
// for initial capacity, then Add()'s three items.
List<int> a = new List<int>(3) { 1, 2, 3, }

ध्यान दें कि Add()विधि को एक आइटम की आवश्यकता नहीं है, उदाहरण के Add()लिए Dictionary<TKey, TValue>दो वस्तुओं को लेने की विधि :

var grades = new Dictionary<string, int>
    {
        { "Suzy", 100 },
        { "David", 98 },
        { "Karen", 73 }
    };

लगभग समान है:

var temp = new Dictionary<string, int>();
temp.Add("Suzy", 100);
temp.Add("David", 98);
temp.Add("Karen", 73);
var grades = temp;

इसलिए, इसे अपनी कक्षा में जोड़ने के लिए, आपको सभी की जरूरत है, जैसा कि उल्लेख किया गया है, लागू है IEnumerable(फिर से, अधिमानतः IEnumerable<T>) और एक या एक से अधिक बनाने के लिए Add():

public class SomeCollection<T> : IEnumerable<T>
{
    // implement Add() methods appropriate for your collection
    public void Add(T item)
    {
        // your add logic    
    }

    // implement your enumerators for IEnumerable<T> (and IEnumerable)
    public IEnumerator<T> GetEnumerator()
    {
        // your implementation
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

फिर आप इसे बीसीएल संग्रह की तरह ही उपयोग कर सकते हैं:

public class MyProgram
{
    private SomeCollection<int> _myCollection = new SomeCollection<int> { 13, 5, 7 };    

    // ...
}

(अधिक जानकारी के लिए, MSDN देखें )


29
अच्छा जवाब, हालांकि मैं ध्यान देता हूं कि आपके पहले उदाहरण में "बिल्कुल समान" कहना बिल्कुल सटीक नहीं है। यह उसी के समान List<int> temp = new List<int>(); temp.Add(1); ... List<int> a = temp; है, aजब तक कि सभी जोड़ नहीं कहा जाता है तब तक चर को प्रारंभ नहीं किया जाता है। अन्यथा ऐसा कुछ करना कानूनी होगा, List<int> a = new List<int>() { a.Count, a.Count, a.Count };जो करने के लिए पागल है।
एरिक लिपर्ट

1
@ user606723: वहाँ के बीच कोई वास्तविक अंतर नहीं है List<int> a; a = new List<int>() { a.Count };औरList<int> a = new List<int>() { a.Count };
Joren

4
@ जोरेन: आप सही हैं; वास्तव में C # विनिर्देश बताता है कि T x = y;जैसा है T x; x = y;, यह तथ्य कुछ विषम परिस्थितियों को जन्म दे सकता है। उदाहरण के लिए, int x = M(out x) + x;पूरी तरह से कानूनी है क्योंकि int x; x = M(out x) + x;कानूनी है।
एरिक लिपर्ट

1
@JamesMichaelHare इसे लागू करना आवश्यक नहीं है IEnumerable<T>; गैर-जेनेरिक IEnumerableसंग्रह इनिशियलाइज़र सिंटैक्स के उपयोग की अनुमति देने के लिए पर्याप्त है।
19

2
यदि आप किसी तरह के संग्रह का उपयोग कर रहे हैं, तो एरिक की बात महत्वपूर्ण है, जो कि आइडीसोपायरी को लागू करता है। using (var x = new Something{ 1, 2 })यदि Addकॉल विफल हो जाती है , तो ऑब्जेक्ट को डिस्पोज़ नहीं किया जाएगा ।
पोरस

11

इसे सिंटैक्टिक शुगर कहा जाता है ।

List<T> "सरल" वर्ग है, लेकिन संकलक आपके जीवन को आसान बनाने के लिए इसे एक विशेष उपचार देता है।

यह एक संग्रह संग्रह कहा जाता है । आपको लागू करने IEnumerable<T>और Addविधि की आवश्यकता है ।


8

के अनुसार सी # संस्करण 3.0 विशिष्टता "संग्रह वस्तु जो करने के लिए एक संग्रह प्रारंभकर्ता लागू किया जाता है ठीक एक टी के लिए एक प्रकार है कि लागू System.Collections.Generic.ICollection का होना चाहिए"

हालाँकि, यह जानकारी इस लेखन के रूप में गलत प्रतीत होती है; नीचे टिप्पणियों में एरिक लिपर्ट का स्पष्टीकरण देखें।


10
वह पेज सटीक नहीं है। इसे मेरे संज्ञान में लाने के लिए धन्यवाद। यह कुछ प्रारंभिक प्री-रिलीज़ प्रलेखन होना चाहिए जो किसी भी तरह कभी भी नष्ट नहीं हुआ। मूल डिज़ाइन को ICollection की आवश्यकता थी, लेकिन यह अंतिम डिज़ाइन नहीं है जिस पर हम बसे थे।
एरिक लिपिपर्ट १३'१२

1
स्पष्टीकरण के लिए धन्यवाद।
ओलिवियर जैकोट-डेसकोम्बर्स

6

यह संग्रह शुरुआती के लिए धन्यवाद काम करता है जिसे मूल रूप से एक ऐड विधि को लागू करने के लिए संग्रह की आवश्यकता होती है और यह आपके लिए काम करेगा।


6

संग्रह initializers के बारे में एक और अच्छी बात यह है कि आप के कई अधिभार हो सकता है Add विधि के और आप उन्हें एक ही शुरुआती में कह सकते हैं! उदाहरण के लिए यह काम करता है:

public class MyCollection<T> : IEnumerable<T>
{
    public void Add(T item, int number)
    {

    }
    public void Add(T item, string text) 
    {

    }
    public bool Add(T item) //return type could be anything
    {

    }
}

var myCollection = new MyCollection<bool> 
{
    true,
    { false, 0 },
    { true, "" },
    false
};

इसे सही अधिभार कहते हैं। इसके अलावा, यह केवल नाम के साथ विधि की तलाश करता है Add, वापसी प्रकार कुछ भी हो सकता है।


0

सिंटैक्स जैसे सरणी को श्रृंखला में बदल दिया जा रहा है Add() कॉल ।

इसे और अधिक दिलचस्प उदाहरण में देखने के लिए, निम्नलिखित कोड पर विचार करें जिसमें मैं दो दिलचस्प चीजें करता हूं जो सी #, 1 में पहले अवैध लगता है) एक आसानी से संपत्ति सेट करना, 2) आरंभीकरण जैसे एक सरणी के साथ एक सूची सेट करना।

public class MyClass
{   
    public MyClass()
    {   
        _list = new List<string>();
    }
    private IList<string> _list;
    public IList<string> MyList 
    { 
        get
        { 
            return _list;
        }
    }
}
//In some other method
var sample = new MyClass
{
    MyList = {"a", "b"}
};

यह कोड पूरी तरह से काम करेगा, हालांकि 1) MyList आसानी से और 2) मैं सरणी आरंभीकरण के साथ एक सूची सेट करता हूं।

यह क्यों काम करता है, इसका कारण यह है कि कोड में जो ऑब्जेक्ट इंटेलाइज़र का हिस्सा होता है, कंपाइलर हमेशा किसी भी {}वाक्यविन्यास की तरह Add()कॉल की एक श्रृंखला में बदल जाता है जो कि पूरी तरह से एक कानूनी रूप से फ़ील्ड पर भी कानूनी रूप से वैध होता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.