यह C # डिक्शनरी इनिशियलाइज़ेशन कैसे सही है?


64

मैं निम्नलिखित पर ठोकर खाई और मैं सोच रहा हूं कि इसने एक सिंटैक्स त्रुटि क्यों नहीं बढ़ाई।

var dict = new Dictionary<string, object>
{
    ["Id"] = Guid.NewGuid(),
    ["Tribes"] = new List<int> { 4, 5 },
    ["MyA"] = new Dictionary<string, object>
    {
        ["Name"] = "Solo",
        ["Points"] = 88
    }
    ["OtherAs"] = new List<Dictionary<string, object>>
    {
        new Dictionary<string, object>
        {
            ["Points"] = 1999
        }
    }
};

ध्यान दें कि "MyA", और "OtherAs" के बीच "," गायब है।

यह वह जगह है जहाँ भ्रम होता है:

  1. कोड संकलित करता है।
  2. अंतिम शब्दकोश "तानाशाह" में केवल तीन तत्व शामिल हैं: "आईडी", "ट्राइब्स", और "माइए"।
  3. "MyA" को छोड़कर सभी के लिए मान सही हैं,
  4. "MyA" "अन्य" के लिए घोषित मूल्य लेता है, जबकि इसके मूल मूल्य को अनदेखा किया जाता है।

यह अवैध क्यों नहीं है? क्या यह डिजाइन द्वारा है?


1
@ यह बताएं कि वह किस बारे में पूछ रहा है। मैंने इसे शार्पलैब में चिपकाया और ऐसा लग रहा है कि शुरू में शब्दकोश की OtherAsकुंजी के रूप में जोड़ा जाएगाMyA । (नाम = सोलो, अंक = 88 प्लस अन्य = सूची <शब्दकोश <स्ट्रिंग, ऑब्जेक्ट >>) इसके अलावा तो कभी भी इसे असाइन नहीं करता है । इसके बजाय यह dicts की सूची रखता है, अब केवल एकल अंक = 1999 में MyAस्लॉट में प्रवेश होता है, जो यह सोचता है कि वहाँ क्या होगा।
Pinkfloydx33

1
पहली टिप्पणी में पेस्ट करने के लिए लिंक बहुत लंबा था। यह वाकई अजीब है। sharplab.io/…
pinkfloydx33

1
हां, मैंने इसे LinqPad के साथ परीक्षण किया है और समान परिणाम मिला है। यकीन नहीं होता कि यहां क्या हो रहा है। आइए देखें कि क्या कुछ C # गुरु यहां कुछ प्रकाश डाल सकते हैं।
स्टीव

1
यदि आप पहले डिक्शनरी को <string, string> and modify Points to "88" में बदलते हैं, तो आप एक कंपाइलर एरर प्राप्त करते हैं, "implicitly convert type 'System.Collections.Generic.List <System.Collections.Generic.Dictionary <string, object' to 'to' string" टाइप करें। " जो वास्तव में मुझे जवाब जानने में मदद करता है!
Pinkfloydx33

2
@OlegI मुझे नहीं लगता कि यह एक संकलक बग है। कई अच्छे स्पष्टीकरण पहले से ही उत्तर में प्रदान किए गए हैं। लेकिन अगर आप कोशिश var test = new Dictionary<string, object> { ["Name"] = "Solo", ["Points"] = 88 }["OtherAs"] = new List<Dictionary<string, object>> { new Dictionary<string, object> { ["Points"] = 1999 } };करेंगे तो आगे बताएंगे।
एमकेआर

जवाबों:


54

गायब अल्पविराम से सभी फर्क पड़ता है। यह ["OtherAs"]इस शब्दकोश पर सूचकांक को लागू करने का कारण बनता है :

new Dictionary<string, object>
{
    ["Name"] = "Solo",
    ["Points"] = 88
}

तो अनिवार्य रूप से आप कह रहे हैं:

new Dictionary<string, object>
{
    ["Name"] = "Solo",
    ["Points"] = 88
}["OtherAs"] = new List<Dictionary<string, object>>
{
    new Dictionary<string, object>
    {
        ["Points"] = 1999
    }
};

ध्यान दें कि यह एक असाइनमेंट एक्सप्रेशन है ( x = y)। यहाँ x"नाम" और "अंक" के साथ शब्दकोष है, जिसके साथ अनुक्रमित "OtherAs"और yहै List<Dictionary<string, object>>। असाइनमेंट अभिव्यक्ति असाइन किए जा रहे मूल्य का मूल्यांकन करता है ( y), जो शब्दकोशों की सूची है।

इस पूरी अभिव्यक्ति का परिणाम तब कुंजी "MyA" को सौंपा गया है, यही कारण है कि "MyA" में शब्दकोशों की सूची है।

आप इस बात की पुष्टि कर सकते हैं कि शब्दकोश के प्रकार को बदलकर यही हो रहा है x:

new Dictionary<int, object>
{
    [1] = "Solo",
    [2] = 88
}
// compiler error saying "can't convert string to int"
// so indeed this indexer is applied to the previous dictionary
["OtherAs"] = new List<Dictionary<string, object>>
{
    new Dictionary<string, object>
    {
        ["Points"] = 1999
    }
}

यहां आपका कोड है, लेकिन पुन: स्वरूपित और कुछ कोष्ठकों में यह वर्णन किया गया है कि संकलक ने इसे कैसे पार्स किया है:

["MyA"] 
= 
(
    (
        new Dictionary<string, object>
        {
            ["Name"] = "Solo",
            ["Points"] = 88
        }["OtherAs"] 
    )
    = 
    (
        new List<Dictionary<string, object>>
        {
            new Dictionary<string, object>
            {
                ["Points"] = 1999
            }
        }
    )
)

1
यह से शब्दकोश का मान प्रकार बदल रहा था objectकरने के लिए stringहै कि मुझे एक ऐसी ही त्रुटि संदेश और दे दी है अहा क्षण है कि इसका जवाब फूट पड़ा। लगता है कि आप इसे मुझे हरा देंगे - मैं अपने फोन पर जवाब टाइप करने का दोष
लगाता

19

यहाँ क्या हो रहा है कि आप एक शब्दकोश बना रहे हैं और फिर उसमें अनुक्रमण कर रहे हैं। अनुक्रमणिका / असाइनमेंट अभिव्यक्ति का परिणाम तब वापस आ जाता है और यही वह है जो MyAशब्दकोश स्लॉट में असाइन किया जा रहा है ।

इस:

["MyA"] = new Dictionary<string, string> 
{
   ["Name"] = "Solo",
   ["Points"] = "88" 
}
["OtherAs"] = new List<Dictionary<string, object>>
{
   new Dictionary<string, object>
   {
       ["Points"] = 1999
   }
}

निम्नलिखित पुसीडो-कोड में विभाजित किया जा सकता है:

var temp = new Dictionary<string, object>
{ 
   ["Name"] = "Solo", 
   ["Points"] = 88 
};
// indexed contains result of assignment
var indexed = temp["OtherAs"] = new List<Dictionary<string, object>>
{
   new Dictionary<string, object>
   {
      ["Points"] = 1999
   }
};
// value is set to result of assignment from previous step
["MyA"] = indexed;
// temp is discarded

दूसरे शब्दकोश के अनुक्रमणिका को असाइन करने का परिणाम लौटाया जाता है (असाइनमेंट दिए गए मान / दाएं हाथ की ओर लौटता है) यह शब्दकोश एक अस्थायी स्थानीय है जो सिर्फ "ईथर में गायब हो जाता है"। अनुक्रमणिका (शब्दकोशों की सूची) का परिणाम अंत में मुख्य शब्दकोश में रखा गया है।

यह एक अजीब मामला है, जिसे objectशब्दकोश मूल्यों के प्रकार के उपयोग के कारण गिरने में आसान बना दिया गया है ।

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