2015-01-21 4 views
12

मैं पढ़ा है कि:सी # 6 का नया संग्रह प्रारंभकर्ता - स्पष्टीकरण?

टीम आम तौर पर initializers पर अन्य रूपों को लागू करने में व्यस्त रहे हैं।

var Dic = new Dictionary<string,int>{ {"x",3}, {"y",7} }; 

वी.एस.

var Dic = new Dictionary<string,int>{ ["x"]=3, ["y"]=7 }; 

मैं नहीं दिख रहा है जहां लाभ है: उदाहरण के लिए अब आप एक शब्दकोश वस्तु

लेकिन को देखकर प्रारंभ कर सकते हैं। यह वही दिखता है। दोनों नाम-मूल्य संग्रह से अधिक कुछ नहीं हैं।
वे वर्ग कोष्ठक के जोड़े और कुछ के लिए अल्पविराम

के लिए घुंघराले ब्रेसिज़ के जोड़े बदली

प्रश्न:

नई सिंटेक्स के उपयोग के लिए अतिरिक्त मूल्य क्या है? एक असली दुनिया का उदाहरण बहुत सराहना की जाएगी।

+2

कोई लाभ नहीं है। यह सिर्फ अधिक नोड-एस्क्यू दिखता है। –

+1

@TravisJ मुझे यह बहुत अजीब लगता है ("कोई लाभ नहीं ..."), अच्छी तरह से '$ xxx' अच्छा है, लेकिन यह सोचने के लिए कि वे घुंघराले ब्रेसिज़ से ब्रैकेट में बदल गए हैं ...? –

+1

यह सिर्फ एक भिन्नता है। मुझे लगता है कि यदि कोई है तो यह लाभ विभिन्न प्रोग्रामिंग पृष्ठभूमि के लोगों के लिए बेहतर पढ़ता है। लेकिन इसके अलावा, यह वास्तव में किसी शब्दकोश की कार्यक्षमता को नहीं बदलता है, या इसे किसी प्रकार की नई जादुई शक्तियों की अनुमति देता है :) –

उत्तर

20

एक शब्दकोश के साथ यहां मुख्य लाभ स्थिरता है। एक शब्दकोश के साथ, प्रारंभिक उपयोग के समान नहीं दिखता था।

उदाहरण के लिए, तुम कर सकते हो:

var dict = new Dictionary<int,string> 
{ 
    {3, "foo"}, 
    {42, "bar"} 
}; 

नई सी # 6 सूचकांक प्रारंभ वाक्य रचना सूचकांक के साथ प्रारंभ वाक्य रचना और अधिक सुसंगत बनाता है:

var dict = new Dictionary<int,string>(); 
dict[3] = "foo"; 
dict[42] = "bar"; 

लेकिन प्रारंभ सिंटैक्स का उपयोग, आप ब्रेसिज़ का इस्तेमाल करना पड़ा उपयोग:

var dict = new Dictionary<int,string> 
{ 
    [3] = "foo", 
    [42] = "bar" 
}; 

हालांकि, एक बड़ा फायदा यह है कि यह sy ntax आपको अन्य प्रकारों को प्रारंभ करने की अनुमति देने का लाभ भी प्रदान करता है। एक इंडेक्सर वाला कोई भी प्रकार इस वाक्यविन्यास के माध्यम से प्रारंभिकरण की अनुमति देगा, जहां पुराना संग्रह प्रारंभकर्ता केवल IEnumerable<T> को लागू करने वाले प्रकारों के साथ काम करता है और Add विधि है। यह Dictionary<TKey,TValue> के साथ काम करने के लिए हुआ, लेकिन इसका मतलब यह नहीं है कि यह किसी भी इंडेक्स आधारित प्रकार के साथ काम करता है।

+2

रीड, ऑफटॉप बंद करें, लेकिन अभी भी संबंधित - मैंने यह भी देखा है (एक वीडियो में, अभी) कि सी # 6 उदाहरण विधि से परे, अतिरिक्त विधि की तलाश भी करता है, मेरा मतलब है कि यह एक विस्तार विधि में हो सकता है। इसलिए यदि किसी के पास 'सम्मिलित करें' नामक विधि है, तो आप 'नया MyIenumerableType <> {{..., ...}, {..., ...}} नहीं कर पाएंगे क्योंकि यह प्रकार है 'एड' विधि नहीं है। लेकिन सी # 6 'एड' को एक्सटेंशन विधि के रूप में भी खोजेगा। (यदि आपके पास कोड पर नियंत्रण नहीं है) –

+1

@RoyiNamir: मैं संक्षेप में [इस उत्तर] में विस्तार जोड़ें विधियों पर जा रहा हूं (http://stackoverflow.com/a/27455822/390278)।यह अतिरिक्त संग्रह संग्रह के साथ काम करने के लिए दरवाजा खोलता है जो कि अधिक भयानक है। –

+1

@RoyiNamir हां, लेकिन इसे अभी भी परिभाषित करने के लिए 'IENumerable ' की आवश्यकता है, इसलिए यह कम सीमित है, लेकिन अभी भी कुछ सीमित है। –

9

पहले मामले में कोड संग्रह प्रारंभकर्ता वाक्यविन्यास का उपयोग करता है।

Collection Initializers:

  1. लागू IEnumerable इंटरफ़ेस संग्रह प्रारंभकर्ता वाक्य रचना, एक वर्ग होगा उपयोग करने में सक्षम होने के लिए।
  2. एक सुलभ Add() विधि परिभाषित करें। (सी # 6/VS2015 के रूप में, यह एक विस्तार विधि हो सकती है)

तो एक वर्ग तो सिंटैक्स का उपयोग कर सकते हैं की तरह परिभाषित किया गया: सभी वस्तुओं IEnumerable हैं या एक ऐड विधि है

public class CollectionInitializable : IEnumerable 
{ 
    public void Add(int value) { ... } 
    public void Add(string key, int value) { ... } 
    public IEnumerator GetEnumerator() { ... } 
} 

var obj = new CollectionInitializable 
{ 
    1, 
    { "two", 3 }, 
}; 

और इसलिए उस वाक्यविन्यास का उपयोग नहीं कर सकते हैं।


दूसरी ओर, कई ऑब्जेक्ट्स परिभाषित (सेटटेबल) इंडेक्सर्स। यह वह जगह है जहां डिकोनरी प्रारंभकर्ता का उपयोग किया जाता है। यह सूचकांक होना समझ में आता है लेकिन यह आवश्यक नहीं है कि IEnumerable हो। शब्दकोश प्रारंभकर्ता के साथ, आपको IEnumerable होने की आवश्यकता नहीं है, आपको Add() विधि की आवश्यकता नहीं है, आपको केवल एक सूचकांक की आवश्यकता है।

एक अभिव्यक्ति में किसी वस्तु को पूरी तरह से प्रारंभ करने में सक्षम होने के नाते आम तौर पर उपयोगी होता है (और कुछ संदर्भों में, एक आवश्यकता)। शब्दकोश प्रारंभकर्ता वाक्यविन्यास संग्रह प्रारंभकर्ताओं का उपयोग करने की कठोर आवश्यकताओं के बिना ऐसा करना आसान बनाता है।

3

प्रति तकनीकी लाभ नहीं है; यह सिर्फ वाक्य रचनात्मक चीनी है (जैसे नई सी # 6 विशेषताओं में से कई)।

वस्तु और संग्रह initializers एलान के तौर पर खेतों और वस्तुओं के गुणों को प्रारंभ करने, या एक संग्रह तत्वों का एक आरंभिक सेट देने के लिए उपयोगी होते हैं: C# feature descriptions PDF, वास्तव में, लालित्य का केवल एक मामले का उल्लेख है। इंडेक्सरों के साथ शब्दकोश और अन्य वस्तुओं को शुरू करना कम सुरुचिपूर्ण है। हम आपको नई वस्तु

+0

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

+0

@Finickyflame जो पूर्व-सी # 6 सिंटैक्स के साथ पहले से ही संभव था (जैसा कि 'अजीब() 'को कॉल करने के विपरीत)। – Gigi

4

यह एक संदिग्ध सुविधा हो सकता है कि किसी भी इंडेक्सर के माध्यम से कुंजी करने के लिए मूल्यों को निर्धारित करने के लिए अनुमति initializers आपत्ति के लिए एक नया वाक्य रचना जोड़ रहे हैं, लेकिन नए वाक्य रचना आप एक ही कई बार स्थापित करने के लिए अनुमति देता है।

 private static Dictionary<string, string> test1 
     = new Dictionary<string, string>() { 
      ["a"] = "b", 
      ["a"] = "c" 
     }; 

अनुमति दी है: यहाँ कुंजी "a" मूल्य "c" है।

इसके विपरीत,

private static Dictionary<string, string> test2 
    = new Dictionary<string, string>() { 
     { "a","b" }, 
     { "a","c" }, 
    }; 

का उपयोग करके अपवाद बनाता है:

Unbehandelte Ausnahme: System.TypeInitializationException: Der Typeninitialisierer für "ConsoleApplication1.Program" hat eine Ausnahme verursacht. 
---> System.ArgumentException: Ein Element mit dem gleichen Schlüssel wurde bereits hinzugefügt. 
    bei System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) 
    bei System.Collections.Generic.Dictionary``2.Insert(TKey key, TValue value, Boolean add) 
    bei System.Collections.Generic.Dictionary``2.Add(TKey key, TValue value) 
    bei ConsoleApplication1.Program..cctor() in Program.cs:Zeile 19. 
    --- Ende der internen Ausnahmestapelüberwachung --- 
    bei ConsoleApplication1.Program.Main(String[] args) 
संबंधित मुद्दे