ট্রাইগেটভ্যালুর চেয়ে সি # অভিধান ব্যবহারের আরও ভাল উপায় কি?


19

আমি নিজেকে প্রায়শই অনলাইনে প্রশ্ন সন্ধান করি এবং অনেকগুলি সমাধানে অভিধান অন্তর্ভুক্ত থাকে। যাইহোক, আমি যখনই এগুলি বাস্তবায়নের চেষ্টা করি তখনই আমি আমার কোডটিতে এই ভয়ঙ্কর মন্তব্য পেয়ে যাই। উদাহরণস্বরূপ প্রতিবার আমি কোনও মান ব্যবহার করতে চাই:

int x;
if (dict.TryGetValue("key", out x)) {
    DoSomethingWith(x);
}

মূলত নিম্নলিখিতটি করতে কোডের 4 টি লাইন রয়েছে: DoSomethingWith(dict["key"])

আমি শুনেছি আউট কীওয়ার্ড ব্যবহার করা একটি বিরোধী প্যাটার্ন কারণ এটি ফাংশনগুলিকে তাদের পরামিতিগুলিকে পরিবর্তিত করে।

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

একইভাবে, আমি প্রায়শই একটি অভিধানে আইটেমগুলি দিয়ে পুনরাবৃত্তি করতে চাই এবং আরও ভাল করতে তালিকার জন্য কী বা মানগুলিকে রূপান্তর করতে দেখতে পাই।

আমার মনে হয় প্রায় সবসময় অভিধান ব্যবহারের আরও ভাল, আরও মার্জিত উপায়, তবে আমার ক্ষতি হয়।


7
অন্যান্য উপায় থাকতে পারে তবে মান পেতে চেষ্টা করার আগে আমি প্রথমে একটি কনটেনস্কি ব্যবহার করি ।
রবি ডি

2
সত্যি, কয়েকটি ব্যতিক্রম ছাড়া, যদি আপনি কি জানেন আপনার অভিধান চাবি সময় এগিয়ে, সেখানে সম্ভবত হয় একটি ভাল উপায়। যদি আপনি না জানেন, ডিক কীগুলি সাধারণত হার্ড-কোডড হওয়া উচিত নয়। শব্দকোষগুলি আধা-কাঠামোগত বস্তু বা ডেটা যেখানে ক্ষেত্রগুলি অন্তত বেশিরভাগ অ্যাপ্লিকেশনটির অর্থেগোনাল সেগুলি নিয়ে কাজ করার জন্য দরকারী । আইএমও, fields ক্ষেত্রগুলি প্রাসঙ্গিক ব্যবসায় / ডোমেন ধারণাগুলি হিসাবে ঘনিষ্ঠ হওয়ার সাথে সাথে, এই ধারণাগুলি নিয়ে কাজ করার জন্য কম সহায়ক অভিধান হবে।
এসভিডজেন

6
@ রবিডি: আপনি যখন এটি করেন তখন আপনাকে সতর্কতা অবলম্বন করতে হবে, কারণ এটি করার ফলে একটি দৌড়ের অবস্থা তৈরি হয়। কনটেনস্কিকে কল করা এবং মান পাওয়ার মধ্যে কীটি মুছে ফেলা সম্ভব।
হোস্টনাম

12
@ ওয়াটসিসনাম: এই অবস্থার অধীনে, একটি সমকালীন অভিধান আরও উপযুক্ত হবে। System.Collections.Genericনেমস্পেসে সংগ্রহগুলি থ্রেড-নিরাপদ নয়
রবার্ট হার্ভে

4
আমি যখন কাউকে ব্যবহার করতে দেখি তার 50% ভাল সময় হয় Dictionary, তারা আসলে কী চায় তা ছিল একটি নতুন শ্রেণি। এই 50% (কেবল) এর জন্য, এটি একটি ডিজাইনের গন্ধ।
ব্লুরাজা - ড্যানি পিফ্লুঘুফুট

উত্তর:


23

ডিকোরিটিজ (সি # বা অন্যথায়) কেবল এমন একটি ধারক যেখানে আপনি কোনও কী এর উপর ভিত্তি করে কোনও মান সন্ধান করেন। বেশ কয়েকটি ভাষায় এটি হ্যাশম্যাপ হিসাবে সবচেয়ে সাধারণ বাস্তবায়নের সাথে মানচিত্র হিসাবে আরও সঠিকভাবে চিহ্নিত।

কী বিবেচনা করতে সমস্যাটি হ'ল কী কী উপস্থিত না থাকলে ঘটে। কিছু ভাষা ফিরে nullবা nilঅন্য কিছু সমতুল্য মান দ্বারা আচরণ করে । নিঃশব্দে কোনও মানের অস্তিত্ব নেই আপনাকে অবহিত করার পরিবর্তে একটি মানকে ডিফল্ট করা।

আরও ভাল বা আরও খারাপের জন্য, সি # লাইব্রেরি ডিজাইনাররা আচরণটি মোকাবেলা করার জন্য একটি প্রতিমা নিয়ে এসেছিলেন। তারা যুক্তি দিয়েছিল যে যে মান নেই তার সন্ধানের জন্য ডিফল্ট আচরণটি একটি ব্যতিক্রম ছোঁড়া। আপনি যদি ব্যতিক্রম এড়াতে চান, তবে আপনি Tryবৈকল্পটি ব্যবহার করতে পারেন । এটি একই দৃষ্টিভঙ্গি যা তারা পূর্ণসংখ্যা বা তারিখ / সময় অবজেক্টগুলিতে স্ট্রিংগুলি পার্স করার জন্য ব্যবহার করে। মূলত, প্রভাবটি এরকম:

T count = int.Parse("12T45"); // throws exception

if (int.TryParse("12T45", out count))
{
    // Does not throw exception
}

এবং এটি অভিধানে এগিয়ে গেছে, যার সূচকটি প্রতিনিধিদের Get(index):

var myvalue = dict["12345"]; // throws exception
myvalue = dict.Get("12345"); // throws exception

if (dict.TryGet("12345", out myvalue))
{
    // Does not throw exception
}

এইভাবেই ভাষাটি ডিজাইন করা হয়েছে।


করা উচিত outভেরিয়েবল নিরুৎসাহিত হবে?

সি # এগুলির প্রথম ভাষা নয় এবং নির্দিষ্ট পরিস্থিতিতে তাদের উদ্দেশ্য রয়েছে। আপনি যদি একটি অত্যন্ত সমবর্তী সিস্টেম তৈরির চেষ্টা করছেন তবে আপনি outএকযোগে সীমাতে ভেরিয়েবল ব্যবহার করতে পারবেন না ।

বিভিন্ন উপায়ে, যদি ভাষা এবং কোর গ্রন্থাগার সরবরাহকারীদের দ্বারা প্রচ্ছন্ন একটি আইডিয়াম থাকে তবে আমি আমার আইপিআইগুলিতে সেই প্রতিমাগুলি গ্রহণ করার চেষ্টা করি। এটি এপিআইকে আরও সামঞ্জস্যপূর্ণ এবং ঘরে বসে ভাষা অনুভব করে। সুতরাং রুবিতে রচিত কোনও পদ্ধতি সি #, সি বা পাইথনে লিখিত পদ্ধতির মতো দেখাচ্ছে না। তাদের প্রত্যেকের বিল্ডিং কোডের একটি পছন্দের পদ্ধতি রয়েছে এবং এটির সাথে কাজ করা আপনার API এর ব্যবহারকারীদের এটি আরও দ্রুত শিখতে সহায়তা করে।


সাধারণভাবে মানচিত্রগুলি কি একটি অ্যান্টি-প্যাটার্ন?

তাদের উদ্দেশ্য রয়েছে তবে অনেক সময় তারা আপনার উদ্দেশ্যটির জন্য ভুল সমাধান হতে পারে। বিশেষত যদি আপনার দ্বি-দিকনির্দেশক ম্যাপিং প্রয়োজন হয়। অনেকগুলি ধারক এবং ডেটা সংগঠিত করার পদ্ধতি রয়েছে। আপনি ব্যবহার করতে পারেন এমন অনেকগুলি পন্থা রয়েছে এবং কখনও কখনও সেই ধারকটি তোলার আগে আপনাকে কিছুটা চিন্তা করা দরকার।

আপনার যদি দ্বি-দিকীয় ম্যাপিং মানগুলির খুব সংক্ষিপ্ত তালিকা থাকে তবে আপনার কেবলমাত্র টিউপসগুলির একটি তালিকা প্রয়োজন। বা স্ট্রাক্টগুলির একটি তালিকা, যেখানে আপনি ম্যাপিংয়ের উভয় পাশে প্রথম ম্যাচটি সহজেই খুঁজে পেতে পারেন।

সমস্যার ডোমেনটি ভাবুন এবং কাজের জন্য উপযুক্ত উপকরণটি চয়ন করুন। যদি একটি না থাকে তবে এটি তৈরি করুন।


4
"তারপরে আপনার কেবলমাত্র টিউপসগুলির একটি তালিকা প্রয়োজন হতে পারে Or - যদি ছোট সেটগুলির জন্য অপ্টিমাইজেশন থাকে তবে সেগুলি গ্রন্থাগারে তৈরি করা উচিত, ব্যবহারকারীর কোডে রাবার স্ট্যাম্পযুক্ত নয়।
ব্লারফ্লায়

আপনি যদি টিপলস বা অভিধানের একটি তালিকা চয়ন করেন তবে এটি বাস্তবায়নের বিশদ। এটি আপনার সমস্যার ডোমেন বোঝার এবং কাজের জন্য সঠিক সরঞ্জামটি ব্যবহার করার প্রশ্ন। স্পষ্টতই, একটি তালিকা বিদ্যমান এবং একটি অভিধান বিদ্যমান। সাধারণ ক্ষেত্রে, অভিধানটি সঠিক, তবে সম্ভবত এক বা দুটি অ্যাপ্লিকেশনের জন্য আপনাকে তালিকাটি ব্যবহার করতে হবে।
বারিন লরিটশ

3
এটি হ'ল, তবে যদি আচরণটি এখনও একইরকম হয় তবে সেই সংকল্পটি গ্রন্থাগারে থাকা উচিত in আমি অন্যান্য ভাষায় কনটেইনার বাস্তবায়ন চালিয়ে গিয়েছি যা অ্যালগরিদমগুলি স্যুইচ করবে যদি কোনও প্রাইরিকে বলা হয় যে এন্ট্রি সংখ্যা কম হবে। আমি আপনার উত্তরের সাথে একমত, তবে এটি একবার বের হয়ে গেলে, এটি একটি লাইব্রেরিতে থাকা উচিত, সম্ভবত স্মলবিডায়ারেশনাল ম্যাপ হিসাবে।
blrfl

5
"আরও ভাল বা আরও খারাপ, সি # লাইব্রেরি ডিজাইনাররা আচরণের সাথে মোকাবিলা করার জন্য একটি প্রতিমা নিয়ে এসেছিলেন।" - আমি মনে করি আপনি মাথার পেরেকটি আঘাত করেছেন: তারা প্রচলিত ব্যবহৃত ব্যবহৃত ব্যবহারের পরিবর্তে একটি প্রতিমা নিয়ে "উঠে এসেছিল", যা returnচ্ছিক রিটার্ন টাইপ।
জার্গ ডব্লু মিট্টাগ

3
@ জার্গডব্লিউমিত্যাগ আপনি যদি এরকম কিছু সম্পর্কে কথা বলছেন Option<T>তবে আমি মনে করি যে এটি সি # ২.০ এ ব্যবহার করা পদ্ধতিটিকে আরও শক্ত করে তুলবে, কারণ এতে প্যাটার্নের মিল নেই।
সোভিক

21

হ্যাশ টেবিল / অভিধানের সাধারণ নীতিগুলি সম্পর্কে এখানে কিছু ভাল উত্তর। তবে আমি ভেবেছিলাম আমি আপনার কোড উদাহরণটি স্পর্শ করব,

int x;
if (dict.TryGetValue("key", out x)) 
{
    DoSomethingWith(x);
}

সি # 7 হিসাবে (যা আমার মনে হয় প্রায় দুই বছরের পুরানো), এটিকে সহজ করা যায়:

if (dict.TryGetValue("key", out var x))
{
    DoSomethingWith(x);
}

এবং অবশ্যই এটি এক লাইনে হ্রাস করা যেতে পারে:

if (dict.TryGetValue("key", out var x)) DoSomethingWith(x);

কীটি যখন বিদ্যমান না থাকে তার জন্য যদি আপনার ডিফল্ট মান থাকে তবে তা হয়ে উঠতে পারে:

DoSomethingWith(dict.TryGetValue("key", out var x) ? x : defaultValue);

সুতরাং আপনি সাম্প্রতিক ভাষা সংযোজন ব্যবহার করে কমপ্যাক্ট ফর্মগুলি অর্জন করতে পারেন।


1
ভি 7 সিনট্যাক্সে ভাল কল, ভাল +1 ব্যবহারের অনুমতি দেওয়ার সময় অতিরিক্ত সংজ্ঞা রেখাটি কাটাতে খুব ভাল বিকল্প
ব্রায়ানএইচ

2
আরও মনে রাখবেন যে "key"উপস্থিত না থাকলে xএটিকে প্রাথমিকভাবে করা হবেdefault(TValue)
পিটার ডুনিহো

জেনেরিক এক্সটেনশন হিসাবে খুব সুন্দর হতে পারে, যেমন অনুরোধ করা হয়েছিল"key".DoSomethingWithThis()
রস প্রেসার

getOrElse("key", defaultValue) নুল অবজেক্ট ব্যবহার করা এখনও আমার প্রিয় প্যাটার্ন হিসাবে আমি ডিজাইনগুলি বেশি পছন্দ করি । সেভাবে কাজ করুন এবং TryGetValueসত্য বা মিথ্যা প্রত্যাবর্তনের বিষয়ে আপনি চিন্তা করবেন না ।
candied_orange

1
আমার মনে হচ্ছে এই উত্তরটি অস্বীকার করার দাবিদার যে কমপ্যাক্ট হওয়ার কারণে কমপ্যাক্ট কোড লেখা খারাপ is এটি আপনার কোডটি পড়া আরও কঠিন করে তুলতে পারে। অতিরিক্তভাবে, আমি যদি সঠিকভাবে স্মরণ করি তবে TryGetValueএটি পারমাণবিক / থ্রেড নিরাপদ নয় যাতে আপনি অস্তিত্বের জন্য খুব সহজেই একটি পরীক্ষা করতে পারেন এবং অন্যটি মূল্য ধরে নিতে এবং পরিচালনা করতে পারেন
মেরি

12

এটি কোনও কোডের গন্ধ বা বিরোধী-প্যাটার্নও নয়, কারণ আউট প্যারামিটারের সাহায্যে ট্রাইগেট-স্টাইলের ফাংশনগুলি ব্যবহার করা আইডোমেটিক সি #। যাইহোক, অভিধানে কাজ করার জন্য সি # তে 3 টি বিকল্প দেওয়া আছে, সুতরাং আপনারা নিশ্চিত হওয়া উচিত যে আপনি আপনার পরিস্থিতির জন্য সঠিকটি ব্যবহার করছেন। আমি মনে করি যে আমি জানি কোথায় আউট প্যারামিটার ব্যবহার করে সমস্যা হচ্ছে এমন গুজবটি এসেছে, তাই আমি শেষ পর্যন্ত এটি পরিচালনা করব।

সি # অভিধানে কাজ করার সময় কী বৈশিষ্ট্যগুলি ব্যবহার করা উচিত:

  1. আপনি যদি নিশ্চিত হন যে কীটি অভিধানে থাকবে তবে আইটেম [টিকেই] বৈশিষ্ট্যটি ব্যবহার করুন
  2. যদি মূলত অভিধানে কীটি থাকা উচিত তবে এটি খারাপ / বিরল / সমস্যাযুক্ত যে এটি নেই, আপনার চেষ্টা করা উচিত ... ধরুন যাতে ত্রুটি উত্থাপিত হয় এবং তারপরে আপনি ত্রুটিটি নিখুঁতভাবে পরিচালনা করার চেষ্টা করতে পারেন
  3. অভিধানে কীটি থাকবে তা আপনি যদি নিশ্চিত না হন তবে আউট প্যারামিটার দিয়ে ট্রিগেট ব্যবহার করুন

এটি ন্যায়সঙ্গত করার জন্য, কেবলমাত্র "মন্তব্যগুলি" এর অধীনে ট্রাইগেটভ্যালু অভিধানের ডকুমেন্টেশনগুলি উল্লেখ করা উচিত :

এই পদ্ধতিটি কনটেনস্কি পদ্ধতি এবং আইটেম [টিকেই] বৈশিষ্ট্যের কার্যকারিতা একত্রিত করে।

...

আপনার কোডটি অভিধানে নেই এমন কীগুলি অ্যাক্সেস করার চেষ্টা করে তবে ট্রিগেটভ্যালু পদ্ধতিটি ব্যবহার করুন। আইটেম [টিকেই] সম্পত্তি দ্বারা নিক্ষিপ্ত কীনটফাউন্ডএক্সেপশন ধরার চেয়ে এই পদ্ধতিটি ব্যবহার করা আরও দক্ষ।

এই পদ্ধতিটি একটি ও (1) ক্রিয়াকলাপের কাছে পৌঁছেছে।

ট্রাইগেটভ্যু উপস্থিত থাকার পুরো কারণটি হ'ল কনটেনস্কি এবং আইটেম [টি কে] ব্যবহার করার আরও সুবিধাজনক উপায় হিসাবে কাজ করা, অভিধানটি দু'বার অনুসন্ধান করা এড়িয়ে চলা - সুতরাং এটির উপস্থিতি নেই এবং ম্যানুয়ালি এটি দুটি জিনিস করা একটি অস্বস্তিকর পছন্দ।

অনুশীলনে, আমি খুব কমই কখনও এই কাঁচা অভিধান ব্যবহার করেছি, এই সাধারণ ম্যাক্সিমের কারণে: সর্বাধিক জেনেরিক শ্রেণি / ধারক চয়ন করুন যা আপনাকে প্রয়োজনীয় কার্যকারিতা দেয় । অভিধানটি কী (উদাহরণস্বরূপ) এর চেয়ে মান দ্বারা সন্ধান করার জন্য ডিজাইন করা হয়নি, সুতরাং যদি এটি এমন কিছু হয় তবে এটি বিকল্প কাঠামোটি ব্যবহার করতে আরও বুদ্ধিমান হতে পারে। আমি মনে করি আমি গত বছরের দীর্ঘ উন্নয়ন প্রকল্পে আমি অভিধানটি একবার ব্যবহার করতে পারি, কারণ এটি আমি যে কাজটি করার চেষ্টা করছিলাম তার জন্য খুব কমই সঠিক সরঞ্জাম ছিল। অভিধান অবশ্যই সি # টুলবক্সের সুইস আর্মি ছুরি নয়।

আউট প্যারামিটারগুলির সাথে কী সমস্যা?

CA1021: পরামিতিগুলি এড়িয়ে চলুন

যদিও রিটার্ন মানগুলি সাধারণ এবং ভারী ব্যবহৃত হয় তবে আউট এবং রেফ প্যারামিটারগুলির সঠিক প্রয়োগের জন্য মধ্যবর্তী ডিজাইন এবং কোডিং দক্ষতা প্রয়োজন। সাধারণ শ্রোতাদের জন্য নকশা করা লাইব্রেরি আর্কিটেক্টদের ব্যবহারকারীদের আউট বা রেফারেন্স পরামিতিগুলি নিয়ে কাজ করার দক্ষতা আশা করা উচিত নয়।

আমি অনুমান করছি যে আপনি যেখানে শুনেছেন আউট প্যারামিটারগুলি একটি অ্যান্টি-প্যাটার্নের মতো কিছু ছিল। সমস্ত নিয়মের মতো, 'কেন' বোঝার জন্য আপনার আরও কাছাকাছি পড়া উচিত, এবং এই ক্ষেত্রে ট্রায়াল প্যাটার্নটি কীভাবে নিয়ম লঙ্ঘন করে না তার একটি স্পষ্ট উল্লেখ রয়েছে :

যে পদ্ধতিগুলি ট্র্যাফিক প্যাটার্ন বাস্তবায়িত করে যেমন System.Int32.TryParse, এই লঙ্ঘনটি বাড়ায় না।


গাইডেন্সের পুরো তালিকাটি এমন কিছু যা আমি আশা করি আরও লোকেরা পড়তে পারে। যারা অনুসরণ করেন, তাদের মূল এটি এখানে। ডকস.মাইক্রোসফট.এইন.ইউএস
পিটার উইন

10

সি # অভিধান থেকে কমপক্ষে দুটি পদ্ধতি অনুপস্থিত রয়েছে যা আমার মতে অন্যান্য ভাষায় প্রচুর পরিস্থিতিতে কোড সাফ করে দেয়। প্রথমটি একটি ফেরত Optionদিচ্ছে, যা আপনাকে স্কালায় নীচের মতো কোড লিখতে দেয়:

dict.get("key").map(doSomethingWith)

দ্বিতীয়টি কোনও ব্যবহারকারী-নির্দিষ্ট ডিফল্ট মান ফিরিয়ে দিচ্ছে যদি কীটি পাওয়া যায় না:

doSomethingWith(dict.getOrElse("key", "key not found"))

Tryপ্যাটার্নের মতো, উপযুক্ত হলে কোনও ভাষা সরবরাহ করে এমন আইডিয়মগুলি ব্যবহার করার জন্য কিছু কথা বলা যেতে পারে , তবে এর অর্থ এই নয় যে আপনাকে কেবল ভাষা সরবরাহ করে তা ব্যবহার করতে হবে। আমরা প্রোগ্রামার। আমাদের নির্দিষ্ট পরিস্থিতিটি বোঝা সহজ করার জন্য নতুন বিমূর্ততা তৈরি করা ঠিক আছে, বিশেষত যদি এটি প্রচুর পুনরাবৃত্তি দূর করে। আপনার যদি ঘন ঘন কিছু প্রয়োজন হয় যেমন রিভার্স লুকআপস বা মানগুলির মাধ্যমে পুনরাবৃত্তি করা হয় তবে এটি ঘটিয়ে দিন। আপনি চান ইন্টারফেস তৈরি করুন।


আমি 2 য় বিকল্পটি পছন্দ করি। হয়তো আমাকে একটি এক্সটেনশন পদ্ধতি বা দুটি লিখতে হবে :)
অ্যাডাম বি

2
প্লাস সাইড সি # এক্সটেনশন পদ্ধতিগুলির অর্থ আপনি এগুলি নিজে প্রয়োগ করতে পারেন
জে.কে.

5

মূলত নিম্নলিখিতটি করতে কোডের 4 টি লাইন রয়েছে: DoSomethingWith(dict["key"])

আমি সম্মতি জানাই যে এটি অনুচিত। এই ক্ষেত্রে আমি ব্যবহার করতে চাই এমন একটি প্রক্রিয়া, যেখানে মানটি কাঠামোর ধরণ is

public static V? TryGetValue<K, V>(
      this Dictionary<K, V> dict, K key) where V : struct => 
  dict.TryGetValue(key, out V v)) ? new V?(v) : new V?();

এখন আমাদের কাছে TryGetValueসেই রিটার্নের একটি নতুন সংস্করণ রয়েছে int?। এরপরে আমরা প্রসারিত করার জন্য একই কৌশল করতে পারি T?:

public static void DoIt<T>(
      this T? item, Action<T> action) where T : struct
{
  if (item != null) action(item.GetValueOrDefault());
}

এবং এখন এটি একসাথে রাখুন:

dict.TryGetValue("key").DoIt(DoSomethingWith);

এবং আমরা একক, পরিষ্কার বিবৃতিতে নেমে আছি।

আমি শুনেছি আউট কীওয়ার্ড ব্যবহার করা একটি বিরোধী প্যাটার্ন কারণ এটি ফাংশনগুলিকে তাদের পরামিতিগুলিকে পরিবর্তিত করে।

আমি কিছুটা কম কড়া কথায় কথায় কথায় কথায় কথায় কথায় কথায় কথায় কথায় কথায় কথায় যেতে পারি যে, সম্ভব হলে মিউটেশনগুলি এড়ানো ভাল ধারণা।

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

তারপরে একটি দ্বিপাক্ষিক অভিধানটি প্রয়োগ করুন বা পান or এগুলি লেখার জন্য সোজা, বা ইন্টারনেটে প্রচুর বাস্তবায়ন উপলব্ধ। এখানে কয়েকটি বাস্তবায়ন রয়েছে, উদাহরণস্বরূপ:

/programming/268321/bidirectional-1-to-1-dictionary-in-c-sharp

একইভাবে, আমি প্রায়শই একটি অভিধানে আইটেমগুলি দিয়ে পুনরাবৃত্তি করতে চাই এবং আরও ভাল করতে তালিকার জন্য কী বা মানগুলিকে রূপান্তর করতে দেখতে পাই।

অবশ্যই, আমরা সবাই করি।

আমার মনে হয় প্রায় সবসময় অভিধান ব্যবহারের আরও ভাল, আরও মার্জিত উপায়, তবে আমার ক্ষতি হয়।

নিজেকে জিজ্ঞাসা করুন "ধরুন আমি যে Dictionaryসঠিক কাজটি করতে চাই তা বাস্তবায়ন করা ছাড়া আমার অন্য কোনও ক্লাস ছিল ; সেই শ্রেণিটি কেমন হবে?" তারপরে, একবার আপনি এই প্রশ্নের উত্তর দিয়েছিলেন, সেই শ্রেণিটি প্রয়োগ করুন । আপনি একজন কম্পিউটার প্রোগ্রামার। কম্পিউটার প্রোগ্রাম লিখে আপনার সমস্যার সমাধান করুন!


ধন্যবাদ। আপনি কি মনে করেন যে অ্যাকশন পদ্ধতিটি আসলে কী করছে সে সম্পর্কে আপনি আরও কিছুটা ব্যাখ্যা করতে পারেন? আমি কর্মে নতুন।
অ্যাডাম বি

1
@ অ্যাডামবি অ্যাকশন এমন একটি বস্তু যা শূন্য পদ্ধতিতে কল করার ক্ষমতা উপস্থাপন করে। যেমন আপনি দেখতে পাচ্ছেন, কলারের পাশে আমরা একটি শূন্য পদ্ধতির নামটি পাস করি যার প্যারামিটার তালিকাটি ক্রিয়াটির জেনেরিক ধরণের আর্গুমেন্টের সাথে মিলে। কলারের দিকে অ্যাকশনটি অন্য কোনও পদ্ধতির মতোই অনুরোধ করা হয়।
এরিক লিপার্ট

1
@AdamB: আপনি মনে করতে পারেন Action<T>খুব অনুরূপ হচ্ছে interface IAction<T> { void Invoke(T t); }, কিন্তু সম্পর্কে কি "কার্যকরী" যে ইন্টারফেস খুব কোমল নিয়ম, এবং কিভাবে সম্পর্কে Invokeকরা যাইবে। আপনি যদি আরও জানতে চান, সি # তে "প্রতিনিধি" সম্পর্কে শিখুন এবং তারপরে ল্যাম্বদা এক্সপ্রেশন সম্পর্কে শিখুন।
এরিক লিপার্ট

ঠিক আছে আমি মনে করি এটি পেয়েছি। সুতরাং ক্রিয়াটি আপনাকে DoIt () এর পরামিতি হিসাবে একটি পদ্ধতি রাখে। এবং যে পদ্ধতি কল।
অ্যাডাম বি

@ অ্যাডামবি: ঠিক ঠিক বলেছেন। এটি "উচ্চ-অর্ডার ফাংশন সহ ফাংশনাল প্রোগ্রামিং" এর একটি উদাহরণ। বেশিরভাগ ফাংশন ডেটা আর্গুমেন্ট হিসাবে গ্রহণ করে; উচ্চতর-অর্ডার ফাংশন নিতে ফাংশন আর্গুমেন্ট হিসাবে এবং তারপর যারা ফাংশন সঙ্গে কাপড় না। আপনি আরও সি ​​# শিখার সাথে সাথে দেখতে পাবেন যে লিনকিউ সম্পূর্ণরূপে উচ্চ-আদেশ ক্রিয়াকলাপের সাথে প্রয়োগ করা হয়েছে।
এরিক লিপার্ট

4

আপনি কেবল TryGetValue()অভিধানে "কী" কী হিসাবে উপস্থিত রয়েছেন কিনা তা জানেন না তবে অন্যটি DoSomethingWith(dict["key"])পুরোপুরি বৈধ কিনা তা নির্মাণের প্রয়োজন কেবল তখনই ।

ContainsKey()পরিবর্তে চেক হিসাবে ব্যবহার করার জন্য একটি "কম নোংরা" পদ্ধতির ব্যবহার হতে পারে ।


6
"একটি" কম নোংরা "পদ্ধতির পরিবর্তে চেক হিসাবে কনটেনসকে () ব্যবহার করা হতে পারে" " আমি একমত না যতটা সাবঅপটিমাল TryGetValue, কমপক্ষে এটি খালি কেস পরিচালনা করতে ভুলে যাওয়া কঠিন করে তোলে। আদর্শভাবে, আমি আশা করি এটি কেবল একটি returnচ্ছিক ফিরে আসবে।
আলেকজান্ডার - মনিকা পুনরায় ইনস্টল করুন

1
ContainsKeyমাল্টিথ্রেডেড অ্যাপ্লিকেশনগুলির পদ্ধতির সাথে একটি সম্ভাব্য সমস্যা রয়েছে যা ব্যবহারের সময় যাচাই করার সময় (ট্যাকটিউইউ) দুর্বলতা। যদি অন্য কোনও থ্রেড কল ContainsKeyএবং এর মধ্যে কীটি মুছে দেয় GetValue?
ডেভিড হামেন

2
@ জ্যাড অপশনালস রচনা। আপনার একটি থাকতে পারেOptional<Optional<T>>
আলেকজান্ডার - মনিকা পুনরায় ইনস্টল করুন

2
@ ডেভিডহ্যামেন পরিষ্কার হওয়ার জন্য আপনার প্রয়োজন TryGetValueহবে ConcurrentDictionary। নিয়মিত
অভিধানটি

2
@ জ্যাড নো, (জাভার optionচ্ছিক ধরণের ধাক্কা, আমাকে আরম্ভ করবেন না)। আমি আরও বিমূর্তভাবে কথা বলছি
আলেকজান্ডার - মনিকা পুনরায় ইনস্টল করুন

2

অন্যান্য উত্তরে দুর্দান্ত পয়েন্ট রয়েছে, সুতরাং আমি সেগুলি এখানে পুনরায় ফিরিয়ে আনব না, তবে পরিবর্তে আমি এই অংশটিতে ফোকাস করব, যা সম্ভবত এখনও অবহেলিত বলে মনে হচ্ছে:

একইভাবে, আমি প্রায়শই একটি অভিধানে আইটেমগুলি দিয়ে পুনরাবৃত্তি করতে চাই এবং আরও ভাল করতে তালিকার জন্য কী বা মানগুলিকে রূপান্তর করতে দেখতে পাই।

আসলে এটি কোনও অভিধানে পুনরাবৃত্তি করা বেশ সহজ, যেহেতু এটি প্রয়োগ করে IEnumerable:

var dict = new Dictionary<int, string>();

foreach ( var item in dict ) {
    Console.WriteLine("{0} => {1}", item.Key, item.Value);
}

আপনি যদি লিনককে পছন্দ করেন তবে তাও ঠিক কাজ করে:

dict.Select(x=>x.Value).WhateverElseYouWant();

সব মিলিয়ে ডিকোরিজগুলি আমি অ্যান্টিপ্যাটার্ন হিসাবে খুঁজে পাই না - এগুলি নির্দিষ্ট ব্যবহারের সাথে একটি নির্দিষ্ট সরঞ্জাম মাত্র।

এছাড়াও আরও সুনির্দিষ্টতার জন্য, দেখুন SortedDictionary(আরও অনুমানযোগ্য পারফরম্যান্সের জন্য আরবি গাছগুলি ব্যবহার করে) এবং SortedList(এটি একটি বিভ্রান্তিকরভাবে নামযুক্ত অভিধান যা অনুসন্ধানের গতির জন্য সন্নিবেশের গতিটিকে ত্যাগ করে, তবে যদি আপনি একটি স্থির, প্রাক- সাজানো সেট)। আমি একটি মামলা যেখানে প্রতিস্থাপন করা হচ্ছে একটি ছিল Dictionaryএকটি সঙ্গে SortedDictionaryদ্রুত সঞ্চালনের মাত্রার একটি আদেশ ফলে (কিন্তু এটি অন্যান্য উপায় বৃত্তাকার খুব ঘটতে পারে)।


1

যদি আপনি মনে করেন যে কোনও অভিধান ব্যবহার করা বিশ্রী হয় তবে এটি আপনার সমস্যার জন্য সঠিক পছন্দ নয়। অভিধানগুলি দুর্দান্ত তবে একজন কমেন্টার লক্ষ্য করেছেন, প্রায়শই এগুলি এমন কোনও কিছুর শর্টকাট হিসাবে ব্যবহৃত হয় যা ক্লাস হওয়া উচিত ছিল। অথবা অভিধানটি নিজেই মূল স্টোরেজ পদ্ধতি হিসাবে সঠিক হতে পারে তবে কাঙ্ক্ষিত পরিষেবা পদ্ধতিগুলি সরবরাহ করার জন্য এর চারপাশে একটি মোড়কের ক্লাস থাকা উচিত।

ডিক্ট [কী] বনাম ট্রাইগেট সম্পর্কে অনেক কিছুই বলা হয়েছে। আমি যেটি প্রচুর ব্যবহার করি তা কীভ্যালিউপায়ার ব্যবহার করে অভিধানে পুনরাবৃত্তি হয়। সম্ভবত এটি কম পরিচিত কন্সট্রাক্ট।

কোনও অভিধানের মূল আশ্বাস হ'ল আইটেমের সংখ্যা বাড়ার সাথে সাথে অন্যান্য সংগ্রহের তুলনায় এটি সত্যিই দ্রুত। যদি আপনার কীটি প্রচুর পরিমাণে বিদ্যমান কিনা তা পরীক্ষা করে দেখতে হয় যে আপনি অভিধানটি আপনার ব্যবহারের জন্য উপযুক্ত কিনা তা নিজেকে জিজ্ঞাসা করতে পারেন। একজন ক্লায়েন্ট হিসাবে আপনার সাধারণত জানা উচিত যে আপনি সেখানে কী রেখেছিলেন এবং কীভাবে জিজ্ঞাসা করা নিরাপদ।

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