সি # তে গেটহ্যাশকোড নির্দেশিকা


136

আমি এসেনশিয়াল সি # 3.0 এবং .NET 3.5 বইতে পড়েছি যে:

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

এটি কি বৈধ গাইডলাইন?

.NET- এ আমি অন্তর্নির্মিত কয়েক প্রকার চেষ্টা করেছি এবং তারা এ জাতীয় আচরণ করে না।


আপনি যদি সম্ভব হয় তবে গ্রহণযোগ্য উত্তরটি পরিবর্তন করতে পারেন to
Giffyguy

উত্তর:


93

উত্তরটি বেশিরভাগ ক্ষেত্রেই, এটি একটি বৈধ গাইডলাইন, তবে সম্ভবত কোনও বৈধ নিয়ম নয়। এটি পুরো ঘটনাটিও বলে না।

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

উদাহরণস্বরূপ, অবজেক্ট এ এর ​​1 টি হ্যাশ দেয় So সুতরাং, এটি হ্যাশ টেবিলের 1 বিনে যায়। তারপরে আপনি অবজেক্ট এ এটিকে পরিবর্তন করুন এটি একটি হ্যাশ ২ ফেরত দেয় যখন একটি হ্যাশ টেবিল এটি সন্ধান করে, এটি 2 বাক্সে দেখায় এবং এটির সন্ধান করতে পারে না object অবজেক্টটি বিন 1 তে অনাথ হয় This সুতরাং হ্যাশ কোডটি অবশ্যই বস্তুর আজীবন পরিবর্তন হয় না , এবং গেটহ্যাশকোড বাস্তবায়নগুলি লেখার কেবল একটি কারণ বাটটিতে ব্যথা।

আপডেট
এরিক লিপার্ট একটি ব্লগ পোস্ট করেছেন যা এতে দুর্দান্ত তথ্য দেয় GetHashCode

অতিরিক্ত আপডেট
আমি উপরে বেশ কয়েকটি পরিবর্তন করেছি:

  1. আমি গাইডলাইন এবং নিয়মের মধ্যে পার্থক্য করেছি।
  2. আমি "অবজেক্টের আজীবন" দিয়েছি।

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

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


1
পরিবর্তনীয় প্রকারের মধ্যে সমতা কীভাবে নির্ধারণ করবেন?
জন বি

9
সাম্যতা নির্ধারণ করার জন্য আপনার গেটহ্যাশকোড ব্যবহার করা উচিত নয়।
জেএসবি ձոգչ

4
@ জেএস ব্যাঙ্গস - এমএসডিএন থেকে: উত্পন্ন ক্লাসগুলি যে গেটহ্যাশকোডকে ওভাররাইড করে তাদের অবশ্যই গ্যারান্টি দিতে সমানকে ওভাররাইড করতে হবে যে গ্যারান্টিযুক্ত দুটি বস্তুর একই হ্যাশ কোড রয়েছে; অন্যথায়, হ্যাশটেবল টাইপটি সঠিকভাবে কাজ করতে পারে না।
জন বি

3
@ জোয়ান ভেনজ: দুটি জিনিস। প্রথমত, এমনকি প্রতিটি প্রয়োগের সময় মাইক্রোসফ্ট গেটহ্যাশকোড পায় না। দ্বিতীয়ত, মানের ধরণগুলি বিদ্যমান মানগুলির পরিবর্তনের পরিবর্তে প্রতিটি মান একটি নতুন উদাহরণ হিসাবে সাধারণত অপরিবর্তনীয়।
জেফ ইয়েটস

17
যেহেতু a.Equals (খ) এর অর্থ অবশ্যই a.GetHashCode () == b.GetHashCode (), সমতা তুলনার জন্য ব্যবহৃত ডেটা পরিবর্তন করা গেলে হ্যাশ কোডটি প্রায়শই পরিবর্তন করতে হয়। আমি বলব যে সমস্যাটি মিউটটেবল ডেটার উপর ভিত্তি করে গেটহ্যাশকোড নয়। সমস্যাটি হ্যাশ টেবিল কী (এবং বাস্তবে সেগুলিকে পরিবর্তিত করছে) হিসাবে পরিবর্তনযোগ্য বস্তুগুলি ব্যবহার করছে। আমি কি ভূল?
নিক্লাস

120

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

তবে প্রথমে প্রথম বিষয়: প্রশ্নের উদ্ধৃত হিসাবে গাইডলাইনটি ভুল।

এখন হুঁশ - তাদের দুটি আছে

প্রথম কারণ : হ্যাশকোডটি যদি কোনও উপায়ে গণনা করা হয় তবে কোনও বস্তুর জীবদ্দশায় এটি পরিবর্তন হয় না, এমনকি যদি বস্তু নিজেই পরিবর্তিত হয় তবে এটি সমান-চুক্তিকে ভেঙে দেবে।

মনে রাখবেন: "যদি দুটি বস্তু সমান হিসাবে তুলনা করে তবে প্রতিটি বস্তুর জন্য গেটহ্যাশকোড পদ্ধতিটি অবশ্যই একই মানটি ফেরত দিতে হবে However তবে, দুটি বস্তু সমান হিসাবে তুলনা না করলে দুটি বস্তুর জন্য গেটহ্যাশকোড পদ্ধতিগুলিকে আলাদা মান দিতে হবে না" "

দ্বিতীয় বাক্যটি প্রায়শই ভুল ব্যাখ্যা করা হয় "একমাত্র নিয়ম হ'ল, বস্তু তৈরির সময় সমান বস্তুর হ্যাশকোড সমান হতে হবে"। কেন জানি না, তবে এটি এখানে বেশিরভাগ উত্তরের সারাংশ সম্পর্কেও।

একটি নাম সম্বলিত দুটি বস্তুর কথা ভাবেন, যেখানে নামটি সমান পদ্ধতিতে ব্যবহৃত হয়: একই নাম -> একই জিনিস। উদাহরণ তৈরি করুন একটি: নাম = জো ইনস্ট্যান্স বি তৈরি করুন: নাম = পিটার

হ্যাশকোড এ এবং হ্যাশকোড বি সম্ভবত এক হবে না। এখন কী ঘটবে, যখন উদাহরণের বি নাম পরিবর্তন করে জো?

প্রশ্ন থেকে প্রাপ্ত গাইডলাইন অনুযায়ী, বি এর হ্যাশকোড পরিবর্তন হবে না। এর ফলাফলটি হবে: A.Equals (B) ==> সত্য তবে একই সাথে: এ.গেটহ্যাশকোড () == বি.গেটহ্যাশকোড () ==> মিথ্যা।

তবে ঠিক এই আচরণটি সমান এবং হ্যাশকোড-চুক্তি দ্বারা স্পষ্টভাবে নিষিদ্ধ।

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


ওয়েলস এখন আসছেন ভাল, প্রথম নজরে, একটি বৈপরীত্য বলে মনে হচ্ছে - যেভাবেই হোক, কোডটি ভেঙে যাবে। তবে কোনও সমস্যাই পরিবর্তিত বা অপরিবর্তিত হ্যাশকোড থেকে আসে না।

সমস্যার উত্সটি এমএসডিএন-তে ভালভাবে বর্ণনা করা হয়েছে:

এমএসডিএন এর হ্যাশটেবল এন্ট্রি থেকে:

মূল অবজেক্টগুলি যতক্ষণ না হ্যাশটেবলের কী হিসাবে ব্যবহৃত হয় সেগুলি অবশ্যই অপরিবর্তনীয় হতে হবে।

এর অর্থ এই:

যে কোনও বস্তু যা একটি হ্যাশভ্যালু তৈরি করে তার হ্যাশভ্যালু পরিবর্তন করা উচিত, যখন বস্তুটি পরিবর্তিত হয় তবে এটি অবশ্যই হবে না - একেবারে অবশ্যই করা উচিত নয় - যখন এটি হ্যাশটেবলের অভ্যন্তরে ব্যবহৃত হয় (বা অন্য কোনও হ্যাশ-ব্যবহারকারী বস্তু অবশ্যই) ।

প্রথমে সহজতম উপায়টি হ্যাশটবেলে কেবলমাত্র ব্যবহারের জন্য অপরিবর্তনীয় অবজেক্টগুলি ডিজাইন করা ছিল, এটি প্রয়োজনের সময় সাধারণ, পরিবর্তনীয় অবজেক্টগুলির অনুলিপি হিসাবে তৈরি করা হবে। অপরিবর্তনীয় বস্তুর অভ্যন্তরে, হ্যাশকোডকে ক্যাশে করা মানসিকভাবে ঠিক, কারণ এটি অপরিবর্তনীয় able

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

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

তবে এটির প্রয়োজন নেই যে সমান-পদ্ধতিটিও পার্শ্ববর্তী ডেটার উপর ভিত্তি করে নয়। সুতরাং, যদি আমি কোনও বস্তু লিখি এবং একটি গেটহ্যাশকোড পদ্ধতি তৈরি করি যা একবারে একবারে একটি মান গণনা করে এবং পরে কলগুলিতে এটি ফেরত দেওয়ার জন্য বস্তুর অভ্যন্তরে সঞ্চয় করে, তবে অবশ্যই আমাকে আবার অবশ্যই করতে হবে: অবশ্যই, অবশ্যই একটি সমান পদ্ধতি তৈরি করতে হবে, যা ব্যবহার করবে তুলনার জন্য সঞ্চিত মানগুলি, যাতে A.Equals (B) কখনই মিথ্যা থেকে সত্যে পরিবর্তিত হয় না। অন্যথায়, চুক্তি ভঙ্গ হবে। এর ফলাফল সাধারণত হবে যে সমান পদ্ধতিটি কোনও অর্থবোধ করে না - এটি মূল রেফারেন্স সমান নয়, তবে এটি কোনও মানও সমান নয়। কখনও কখনও, এটি উদ্দেশ্যমূলক আচরণ হতে পারে (যেমন গ্রাহক রেকর্ডস), তবে সাধারণত তা হয় না।

সুতরাং, কেবলমাত্র গেটহ্যাশকোডের ফলাফল পরিবর্তন করুন, যখন অবজেক্টের ডেটা পরিবর্তন হয় এবং যদি হ্যাশের অভ্যন্তরের অবজেক্টের তালিকা বা বস্তু ব্যবহার করে উদ্দেশ্য হয় (বা কেবল সম্ভব) তবে অবজেক্টটিকে হয় অপরিবর্তনীয় করে তুলুন বা এর জন্য ব্যবহারের জন্য কেবলমাত্র পঠিত পতাকা তৈরি করুন অবজেক্টযুক্ত একটি হ্যাশ তালিকার জীবনকাল।

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


23
এই বিশদ ব্যাখ্যার জন্য +1 (আমি পারলে আরও দিতাম)
অলিভার

5
ভার্জোজ ব্যাখ্যার কারণে +1 এটি অবশ্যই আরও ভাল উত্তর! :)
জো

9

এমএসডিএন থেকে

যদি দুটি বস্তু সমান হিসাবে তুলনা করে তবে প্রতিটি বস্তুর জন্য গেটহ্যাশকোড পদ্ধতিতে একই মানটি দিতে হবে। যাইহোক, যদি দুটি বস্তু সমান হিসাবে তুলনা না করে তবে দুটি বস্তুর জন্য গেটহ্যাশকোড পদ্ধতিগুলিকে বিভিন্ন মান ফেরত দিতে হবে না।

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

সেরা পারফরম্যান্সের জন্য, একটি হ্যাশ ফাংশন অবশ্যই সমস্ত ইনপুটের জন্য এলোমেলো বিতরণ উত্পন্ন করে।

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


সম্পাদনা করুন :

এমএসডিএন থেকেও:

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

থেকে দুটিই MSDN এর hashtable এন্ট্রি :

মূল অবজেক্টগুলি যতক্ষণ না হ্যাশটেবলের কী হিসাবে ব্যবহৃত হয় সেগুলি অবশ্যই অপরিবর্তনীয় হতে হবে।

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

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


গেটহ্যাশকোড () হ্যাশটেবলে ব্যবহারের জন্য ডিজাইন করা হয়েছে, এটি এই ফাংশনের একমাত্র পয়েন্ট।
স্কোলিমা

@ এসকোলিমা - এমএসডিএন ডকুমেন্টেশন এর সাথে সঙ্গতিপূর্ণ নয়। মিউটেবল অবজেক্টগুলি গেটহ্যাশকোড () প্রয়োগ করতে পারে এবং অবজেক্টের মান পরিবর্তনের সাথে সাথে বিভিন্ন মান প্রদান করতে পারে। হ্যাশ টেবিলগুলি অবশ্যই অপরিবর্তনীয় কীগুলি ব্যবহার করতে পারে। সুতরাং, আপনি হ্যাশটেবল ব্যতীত অন্য কোনও কিছুর জন্য গেটহ্যাশকোড () ব্যবহার করতে পারেন।
জন বি

9

আমি মনে করি যে গেটহ্যাশকোড সম্পর্কিত ডকুমেন্টেশনগুলি কিছুটা বিভ্রান্তিকর।

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

দুটিই MSDN:

একটি হ্যাশ ফাংশনটিতে নিম্নলিখিত বৈশিষ্ট্য থাকতে হবে:

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

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

public class SomeThing
{
      public string Name {get; set;}

      public override GetHashCode()
      {
          return Name.GetHashcode();
      }

      public override Equals(object other)
      {
           SomeThing = other as Something;
           if( other == null ) return false;
           return this.Name == other.Name;
      }
}

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

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

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


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

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

8

এটি ভাল পরামর্শ। বিষয়টি নিয়ে ব্রায়ান পেপিনের কী বক্তব্য রয়েছে তা এখানে:

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


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

@ এরিক টুটম্যান: আমি যদি কোনও কাঠামোর জন্য বিধিগুলি লিখতাম, তবে আমি নির্দিষ্ট করে দিতাম যে কোনও জোড় অবজেক্টের জন্য Xএবং Yএকবার X.Equals(Y)বা Y.Equals(X)বলা হয়েছিল, ভবিষ্যতের সমস্ত কলগুলির একই ফল পাওয়া উচিত। কেউ যদি সাম্যের আরও কিছু সংজ্ঞা ব্যবহার করতে চায় তবে একটি ব্যবহার করুন EqualityComparer<T>
সুপারক্যাট

5

আপনার প্রশ্নের সরাসরি উত্তর দিচ্ছেন না, তবে - আপনি যদি পুনঃশিকার ব্যবহার করেন তবে এটির জন্য এমন একটি বৈশিষ্ট্য রয়েছে যা আপনার জন্য একটি যুক্তিসঙ্গত গেটহ্যাশকোড বাস্তবায়ন (পাশাপাশি সমান পদ্ধতি) জেনারেট করে। হ্যাশকোড গণনা করার সময় আপনি অবশ্যই শ্রেণীর কোন সদস্যকে বিবেচনা করা হবে তা নির্দিষ্ট করতে পারেন।


ধন্যবাদ, আসলে আমি কখনই রেশার্পার ব্যবহার করিনি তবে আমি এটি প্রায়শই উল্লেখ করা দেখি, তাই আমার এটি চেষ্টা করা উচিত।
জোয়ান ভেনজে

+1 পুনঃভাগকারী যদি এটির একটি থাকে তবে এটি একটি দুর্দান্ত গেটহ্যাশকোড বাস্তবায়ন উত্পন্ন করে।
মেগান

5

মার্ক ব্রুকস থেকে এই ব্লগ পোস্ট দেখুন:

ভিটিও, আরটিও এবং গেটহ্যাশকোড () - ওহ, আমার!

এবং তারপরে ফলোআপ পোস্টটি পরীক্ষা করুন (আমি নতুন হিসাবে লিঙ্ক করতে পারছি না, তবে দীক্ষাল নিবন্ধে একটি লিঙ্ক আছে) যা আরও আলোচনা করে এবং প্রাথমিক বাস্তবায়নে কিছু ছোটখাটো দুর্বলতা coversেকে রাখে।

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


4

হ্যাশকোড কখনই পরিবর্তিত হয় না, তবে হ্যাশকোডটি কোথা থেকে আসছে তা বোঝাও গুরুত্বপূর্ণ।

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

সংক্ষেপে:

মান প্রকার শব্দার্থবিদ্যা - হ্যাশকোড মান দ্বারা সংজ্ঞায়িত করা হয় রেফারেন্স টাইপ শব্দার্থবিদ্যা - হ্যাশকোড কিছু আইডি দ্বারা সংজ্ঞায়িত করা হয়

আমি আপনাকে এরিক ইভান্স দ্বারা ডোমেন ড্রাইভড ডিজাইন পড়ার পরামর্শ দিচ্ছি, যেখানে সে মান সত্তা বনাম সত্তাগুলিতে চলে যায় (যা আমি উপরে করার চেষ্টা করলাম যা কমবেশি কম) যদি এটি এখনও বোঝা যায় না।


এটি আসলে সঠিক নয়। একটি নির্দিষ্ট উদাহরণের জন্য হ্যাশ কোডটি অবশ্যই স্থির থাকতে হবে। মান ধরণের ক্ষেত্রে এটি প্রায়শই ঘটে থাকে যে প্রতিটি মান একটি অনন্য উদাহরণ এবং তাই হ্যাশটি পরিবর্তিত হয় বলে মনে হয় তবে বাস্তবে এটি একটি নতুন উদাহরণ।
জেফ ইয়েটস

আপনি ঠিক বলেছেন, মানের প্রকারগুলি অপরিবর্তনীয় তাই তারা পরিবর্তনকে বাদ দেয়। ভালো বল ধরা.
ডেভিডএন

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