এই সি # অভিধানের সূচনাটি কীভাবে সঠিক?


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
        }
    }
};

লক্ষ্য করুন যে "মাইএ" এবং "অন্যান্যএএস" এর মধ্যে "," অনুপস্থিত।

এখানেই বিভ্রান্তি ঘটে:

  1. কোডটি সংকলন করে।
  2. চূড়ান্ত অভিধান "ডিক" এ কেবলমাত্র তিনটি উপাদান রয়েছে: "আইডি", "উপজাতি" এবং "মাইএ"।
  3. "মাইএ" ব্যতীত সকলের জন্য মানটি সঠিক,
  4. "মাইএ" "অন্যান্যএএস" এর জন্য ঘোষিত মান গ্রহণ করে, যখন এর আসল মানটিকে অগ্রাহ্য করা হয়।

কেন এটি অবৈধ নয়? এটা কি ডিজাইন করে?


1
@ স্টিভ যে তিনি যা জিজ্ঞাসা করছেন। আমি sharplab এই আটকানো এবং এটি প্রাথমিকভাবে দেখে মনে হচ্ছে OtherAsকি মধ্যে একটি কী হিসাবে যোগ পরার হবেMyA অভিধান। (নাম = একক, পয়েন্ট = 88 প্লাস অন্যান্যএএস = তালিকা <ডিকশনারী <স্ট্রিং, অবজেক্ট >>) এটিকে এর পরে কখনও বরাদ্দ করে না । পরিবর্তে এটি ডিক্টের তালিকা রাখে, এখন MyAস্লটে কেবলমাত্র একক পয়েন্ট = 1999 এন্ট্রি রয়েছে যাতে কেউ কী ভাবেন সেটিকে ওভাররাইড করে।
গোলাপিফ্লোয়েডএক্স 33

1
লিঙ্কটি প্রথম মন্তব্যে আটকানোর জন্য দীর্ঘ ছিল। এটা সত্যিই অদ্ভুত। ত্রাপলাব.আইও /…
গোলাপিফ্লোয়েডএক্স 33

1
হ্যাঁ, আমি এটি লিনকপ্যাড দিয়ে পরীক্ষা করেছি এবং একই ফল পেয়েছি। এখানে কী চলছে তা নিশ্চিত নয়। আসুন দেখে নেওয়া যাক যে কোনও সি # গুরু এখানে কিছু আলোকপাত করতে পারে।
স্টিভ

1
আপনি যদি প্রথম <string, string> and modify Points to অভিধানটি "88" তে পরিবর্তন করেন তবে আপনি একটি সংকলক ত্রুটি পেয়ে যান "স্পষ্টতই 'সিস্টেম.কলেশনস.জেনারিক.লাইস্ট <সিস্টেম.কলেশনস.জেনেরিক.ডায়ার্নি <স্ট্রিং, অবজেক্ট >>' থেকে 'স্ট্রিং'" রুপান্তর করতে পারবেন না " যা আসলে আমাকে উত্তরটি খুঁজে পেতে সহায়তা করেছিল!
গোলাপিফ্লোয়েডএক্স 33

2
@ ওলিগি আমি এটি একটি সংকলক বাগ মনে করি না। ইতিমধ্যে উত্তরে সরবরাহ করা অনেক ভাল ব্যাখ্যা। তবে আপনি যদি চেষ্টা করেন তবে 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), যা অভিধানের তালিকা।

এই পুরো প্রকাশের ফলাফলটি তখন "মাইএ" কীতে অর্পিত হয়, এজন্যই "মাইএ" অভিধানের তালিকা রয়েছে।

আপনি অভিধানের ধরণ পরিবর্তন করে যা ঘটছে তা নিশ্চিত করতে পারেন 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
   }
}

নিম্নলিখিত psuedo কোড মধ্যে বিভক্ত করা যেতে পারে:

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অভিধানের মানগুলির ধরণ হিসাবে ব্যবহারের কারণে এটি সহজেই পড়ে যায় ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.