সম্পত্তি প্রাপ্তি বা সেটারের মধ্যে থেকে কখন ব্যতিক্রম ছুঁড়ে ফেলা উপযুক্ত? কখন এটি উপযুক্ত নয়? কেন? বিষয়টিতে বাহ্যিক নথিগুলির লিঙ্কগুলি সহায়ক হবে ... গুগল আশ্চর্যরকমভাবে সামান্য পরিণত হয়েছিল।
সম্পত্তি প্রাপ্তি বা সেটারের মধ্যে থেকে কখন ব্যতিক্রম ছুঁড়ে ফেলা উপযুক্ত? কখন এটি উপযুক্ত নয়? কেন? বিষয়টিতে বাহ্যিক নথিগুলির লিঙ্কগুলি সহায়ক হবে ... গুগল আশ্চর্যরকমভাবে সামান্য পরিণত হয়েছিল।
উত্তর:
মাইক্রোসফ্টের http://msdn.microsoft.com/en-us/library/ms229006.aspx এ কীভাবে বৈশিষ্ট্যগুলি ডিজাইন করা যায় সে সম্পর্কে তার প্রস্তাবনা রয়েছে
মূলত, তারা প্রস্তাব দেয় যে সম্পত্তি প্রাপ্তারা হালকা ওজনের অ্যাক্সেসর হতে হবে যা কল করা সর্বদা নিরাপদ। যদি ব্যতিক্রমগুলি আপনার ছুঁড়ে ফেলার দরকার হয় তবে তারা পুনরায় ডিজাইনিং গেটারদেরকে পদ্ধতি হিসাবে প্রস্তাব দেয়। সেটারদের জন্য তারা নির্দেশ করে যে ব্যতিক্রমগুলি উপযুক্ত এবং গ্রহণযোগ্য ত্রুটি পরিচালনার কৌশল।
সূচকদের জন্য, মাইক্রোসফ্ট ইঙ্গিত দেয় যে এটি প্রাপ্তি এবং সেটটার উভয়েরই ব্যতিক্রম ছুঁড়ে ফেলার জন্য গ্রহণযোগ্য। এবং প্রকৃতপক্ষে। নেট গ্রন্থাগারের অনেক সূচক এটি করে। সর্বাধিক সাধারণ ব্যতিক্রম হচ্ছে ArgumentOutOfRangeException
।
সম্পত্তি অর্জনকারীদের ব্যতিক্রম আপনি ছুঁড়ে ফেলতে চান না এমন কয়েকটি বেশ কয়েকটি ভাল কারণ রয়েছে:
obj.PropA.AnotherProp.YetAnother
- এই ধরণের সিনট্যাক্সের সাহায্যে ব্যতিক্রম ক্যাপ স্টেটমেন্টগুলি ইনজেক্ট করার সিদ্ধান্ত নিতে সমস্যা হয়।পার্শ্ব নোট হিসাবে, একজনকে সচেতন হওয়া উচিত যে কেবল কোনও সম্পত্তি ব্যতিক্রম ছুঁড়ে দেওয়ার জন্য তৈরি করা হয়নি , তার অর্থ এই নয় যে এটি হবে না; এটি সহজেই কোডিং কোড হতে পারে যা করে। এমনকি কোনও নতুন অবজেক্ট (স্ট্রিংয়ের মতো) বরাদ্দের সাধারণ কাজটিও ব্যতিক্রম হতে পারে। আপনার কোডটি সর্বদা আপনার প্রতিরক্ষামূলকভাবে লিখতে হবে এবং আপনি যা কিছু চান তার থেকে ব্যতিক্রম আশা করে।
সেটারগুলি থেকে ব্যতিক্রম ছোঁড়াতে কোনও ভুল নেই। সর্বোপরি, কোন প্রদত্ত সম্পত্তির জন্য মানটি বৈধ নয় তা বোঝানোর জন্য এর চেয়ে ভাল উপায় কী?
প্রাপ্তদের জন্য, এটি সাধারণত ভ্রূণ্য হয় এবং এটি খুব সহজেই ব্যাখ্যা করা যায়: একটি সম্পত্তি প্রাপ্ত ব্যক্তি, সাধারণভাবে, কোনও বস্তুর বর্তমান অবস্থা রিপোর্ট করে; সুতরাং, একমাত্র ক্ষেত্রে যেখানে গ্রাহকের পক্ষে নিক্ষিপ্ত হওয়া যুক্তিযুক্ত তা যখন রাষ্ট্রটি অবৈধ। তবে সাধারণত আপনার ক্লাসগুলি ডিজাইন করা ভাল ধারণা হিসাবে বিবেচিত হয় যে প্রাথমিকভাবে কোনও অবৈধ অবজেক্ট পাওয়া সহজভাবে সম্ভব নয়, বা এটি সাধারণ উপায়ে অবৈধ অবস্থায় ফেলে দেওয়া (যেমন, সর্বদা কনস্ট্রাক্টরগুলিতে সম্পূর্ণ সূচনা নিশ্চিত করা এবং রাষ্ট্রের বৈধতা এবং শ্রেণি আক্রমণকারীদের ক্ষেত্রে পদ্ধতিগুলি ব্যতিক্রম-নিরাপদ করার চেষ্টা করুন)। যতক্ষণ আপনি এই নিয়মটি অবিচল থাকেন ততক্ষণ আপনার সম্পত্তি প্রাপ্তিরা কখনই এমন পরিস্থিতিতে পড়বেন না যেখানে তাদের অবৈধ অবস্থার প্রতিবেদন করতে হবে এবং এভাবে কখনও ছুঁড়ে দেওয়া হবে না।
আমি জানি একটি ব্যতিক্রম আছে এবং এটি আসলে একটি বরং প্রধান এক: যে কোনও বস্তু বাস্তবায়ন করছে IDisposable
। Dispose
অবৈধ অবস্থায় অবজেক্ট আনার উপায় হিসাবে নির্দিষ্টভাবে লক্ষ্যযুক্ত ObjectDisposedException
এবং সেই ক্ষেত্রে ব্যবহার করার জন্য একটি বিশেষ ব্যতিক্রম শ্রেণি রয়েছে । ObjectDisposedException
সম্পত্তি Dispose
নিষ্পত্তির (এবং নিজেকে বাদ দিয়ে) কোনও শ্রেণীর সদস্যের কাছ থেকে ফেলে দেওয়া অবজেক্টটি নিষ্পত্তি হওয়ার পরে একেবারে স্বাভাবিক ।
IDisposable
পরে অকেজো করা উচিত Dispose
। সদস্যকে আহ্বান জানাতে যদি এমন কোনও সংস্থান ব্যবহারের প্রয়োজন হয় যা Dispose
অনুপলব্ধ হয়ে উঠেছে (যেমন সদস্যটি কোনও প্রবাহ বন্ধ করা হয়েছে যা থেকে ডেটা পড়বে) ObjectDisposedException
সদস্যটিকে যেমন ফাঁস হওয়ার পরিবর্তে নিক্ষেপ করা উচিত ArgumentException
, তবে যদি কারও সাথে এমন একটি বৈশিষ্ট্য রয়েছে যা প্রতিনিধিত্ব করে নির্দিষ্ট ক্ষেত্রের মানগুলি, প্রয়োজনের তুলনায় এই জাতীয় সম্পত্তিগুলি নিষ্পত্তির পরে পড়ার অনুমতি দেওয়া (শেষ ধরণের মানগুলি উপস্থাপন করা) অনেক বেশি সহায়ক বলে মনে হচ্ছে ...
Dispose
এগুলি সমস্ত সম্পত্তি পড়ার আগে পর্যন্ত পিছিয়ে দেওয়া হবে। কিছু ক্ষেত্রে যেখানে একটি থ্রেড কোনও অবজেক্টে ব্লকিং রিডিং ব্যবহার করতে পারে যখন অন্যটি এটি বন্ধ করে দেয় এবং যেখানে ডেটা আগে যে কোনও সময় Dispose
আসতে পারে Dispose
, আগত ডেটাগুলি কেটে ফেলতে সহায়ক হতে পারে তবে আগের প্রাপ্ত ডেটাগুলি পড়ার অনুমতি দেয় allow কারওর মধ্যে Close
এবং Dispose
এমন পরিস্থিতিতে কোনও কৃত্রিম পার্থক্য জোর করা উচিত নয় যেখানে অন্যথায় কারও অস্তিত্বের প্রয়োজন নেই।
Get...
পরিবর্তে কোনও পদ্ধতি হিসাবে এটি আরও ভাল । এখানে একটি ব্যতিক্রম হ'ল যখন আপনাকে একটি বিদ্যমান ইন্টারফেস প্রয়োগ করতে হবে যার জন্য আপনাকে কোনও সম্পত্তি সরবরাহ করতে হবে।
এটি মোটামুটিভাবে কখনও কখনও উপযুক্ত হিসাবে পাওয়া যায় না এবং কখনও কখনও সেটারের জন্যও উপযুক্ত appropriate
এই ধরণের প্রশ্নের সর্বোত্তম উত্স হ'ল কোয়ালিনা এবং আব্রামের "ফ্রেমওয়ার্ক ডিজাইনের গাইডলাইনস"; এটি একটি সীমাবদ্ধ বই হিসাবে উপলভ্য এবং এর বড় অংশগুলি অনলাইনেও উপলব্ধ।
বিভাগ 5.2 থেকে: সম্পত্তি নকশা
সম্পত্তি প্রাপ্তকারীদের থেকে ব্যতিক্রম ছোঁড়া AVOID। সম্পত্তি প্রাপ্তিগুলি সাধারণ ক্রিয়াকলাপ হওয়া উচিত এবং পূর্বশর্ত থাকা উচিত নয়। যদি কোনও প্রাপ্তি ব্যতিক্রম ছুঁড়ে ফেলতে পারে তবে সম্ভবত এটি একটি পদ্ধতি হিসাবে পুনরায় ডিজাইন করা উচিত। নোট করুন যে এই বিধি সূচকগুলির ক্ষেত্রে প্রযোজ্য নয়, যেখানে আমরা আর্গুমেন্টগুলি বৈধ করার জন্য ব্যতিক্রমগুলি আশা করি expect
মনে রাখবেন যে এই নির্দেশিকাটি কেবল সম্পত্তি প্রাপ্তদের ক্ষেত্রে প্রযোজ্য। কোনও সম্পত্তি সেটারে একটি ব্যতিক্রম ছুঁড়ে ফেলা ঠিক।
ObjectDisposedException
অবজেক্টটি একবার ডাকার পরে নিক্ষেপ করার কথা বিবেচনা করবে Dispose()
এবং পরবর্তীকালে কোনও সম্পত্তির মান জিজ্ঞাসা করবে? দেখে মনে হচ্ছে দিকনির্দেশটি "সম্পত্তি প্রাপ্তদের থেকে ব্যতিক্রম ছোঁড়া এড়াতে হবে, যদি না অবজেক্টটি নিষ্পত্তি না করা হয় তবে কোন ক্ষেত্রে আপনি অবজেক্টডিসপোজড এক্সেকপশন নিক্ষেপ করার বিষয়টি বিবেচনা করা উচিত"।
ব্যতিক্রমগুলির একটি দুর্দান্ত উপায় হ'ল এটিকে নিজের এবং অন্যান্য বিকাশকারীদের নীচের মত কোড নথিতে ব্যবহার করুন:
ব্যতিক্রম ব্যতিক্রমী প্রোগ্রামের রাজ্যের ক্ষেত্রে হওয়া উচিত। এর অর্থ এটি যেখানে খুশি লিখতে ভাল!
আপনি গিটারগুলিতে তাদের রাখার একটি কারণ হ'ল কোনও শ্রেণীর API ডকুমেন্ট করা - যদি সফ্টওয়্যারটি যদি কোনও প্রোগ্রামার এটির ভুল ব্যবহারের চেষ্টা করার সাথে সাথে একটি ব্যতিক্রম ছুঁড়ে দেয় তবে তারা এটিকে ভুল ব্যবহার করবে না! উদাহরণস্বরূপ, যদি আপনার কোনও ডেটা পাঠের প্রক্রিয়া চলাকালীন বৈধতা থাকে তবে ডেটাতে মারাত্মক ত্রুটি থাকলে প্রক্রিয়াটির ফলাফলটি চালিয়ে যেতে এবং অ্যাক্সেস করতে সক্ষম হবেন তা বোধগম্য নয়। এই ক্ষেত্রে আপনি যদি অন্য কোনও প্রোগ্রামার এই শর্তটি পরীক্ষা করে থাকেন কিনা তা নিশ্চিত করার জন্য ত্রুটি থাকলে যদি আপনি আউটপুট নিক্ষেপ করতে চান।
এগুলি একটি সাবসিস্টেম / পদ্ধতি / যাই হোক না কেন অনুমান এবং গণ্ডিগুলি ডকুমেন্ট করার একটি উপায়। সাধারণ ক্ষেত্রে এগুলি ধরা উচিত নয়! এটি এ কারণেইও হয় যে এগুলি কখনই ছুঁড়ে ফেলা হয় না যদি সিস্টেমটি প্রত্যাশিতভাবে একসাথে কাজ করে: যদি কোনও ব্যতিক্রম ঘটে তা দেখায় যে কোডের কোনও অংশের অনুমানগুলি পূরণ হয় নি - যেমন এটি চারপাশের বিশ্বের সাথে যোগাযোগ করছে না এটি মূলত ছিল আপনি যদি এই লক্ষ্যে লেখা একটি ব্যতিক্রম ধরা পড়েন তবে এর অর্থ সম্ভবত সিস্টেমটি একটি অনির্দেশীয় / অসঙ্গত অবস্থায় প্রবেশ করেছে - এটি শেষ পর্যন্ত ডেটা বা অনুরূপের ক্রাশ বা দুর্নীতিতে ডেকে আনতে পারে যা সনাক্ত / ডিবাগ করা খুব কঠিন হতে পারে।
ব্যতিক্রম বার্তাগুলি ত্রুটিগুলির প্রতিবেদন করার খুব মোটা উপায় they এগুলি ম্যাসেজে সংগ্রহ করা যায় না এবং কেবল সত্যিকারের স্ট্রিং থাকে। এটি তাদের ইনপুট ডেটাতে সমস্যা রিপোর্ট করার জন্য অনুপযুক্ত করে তোলে। স্বাভাবিক চলমান অবস্থায় সিস্টেম নিজেই একটি ত্রুটি অবস্থায় প্রবেশ করা উচিত নয়। এর ফলস্বরূপ এগুলির মধ্যে থাকা বার্তাগুলি প্রোগ্রামারদের জন্য নকশাকৃত করা উচিত এবং ব্যবহারকারীদের জন্য নয় - যে জিনিসগুলি ইনপুট ডেটাতে ভুল তা আবিষ্কার করা এবং আরও উপযুক্ত (কাস্টম) ফর্ম্যাটে ব্যবহারকারীদের কাছে রিলে করা যেতে পারে।
এই নিয়মের ব্যতিক্রম (হা হা!) আইও এর মতো জিনিস যেখানে ব্যতিক্রমগুলি আপনার নিয়ন্ত্রণে থাকে না এবং আগাম পরীক্ষা করা যায় না।
এটি সমস্ত এমএসডিএন-তে নথিভুক্ত করা হয়েছে (অন্যান্য উত্তরের সাথে যুক্ত হিসাবে) তবে এখানে থাম্বের একটি সাধারণ নিয়ম ...
সেটারে, আপনার সম্পত্তিটি উপরে এবং প্রকারের বাইরে বৈধ হওয়া উচিত। উদাহরণস্বরূপ, ফোননম্বার নামে পরিচিত কোনও সংস্থার সম্ভবত রেজেক্স বৈধতা থাকা উচিত এবং ফর্ম্যাটটি বৈধ না হলে একটি ত্রুটি ছুঁড়ে ফেলা উচিত।
প্রাপ্তদের জন্য, সম্ভবত যখন মানটি শূন্য থাকে তবে সম্ভবত কলিং কোডটি (ডিজাইনের নির্দেশিকা অনুসারে) আপনি হ্যান্ডেল করতে চান এমন সম্ভবত।
এমএসডিএন: স্ট্যান্ডার্ড ব্যাতিক্রমের ধরণগুলি ছোঁড়াচ্ছে
এটি একটি খুব জটিল প্রশ্ন এবং উত্তর আপনার অবজেক্টটি কীভাবে ব্যবহৃত হবে তার উপর নির্ভর করে। থাম্বের নিয়ম হিসাবে, সম্পত্তি প্রাপ্তি এবং সেটটারগুলি যে "দেরীতে বাইন্ডিং" থাকে তার ব্যতিক্রমগুলি ছুঁড়ে ফেলা উচিত নয়, যখন প্রয়োজন দেখা দেয় তখন একচেটিয়াভাবে "প্রারম্ভিক বাঁধাই" থাকা সম্পত্তিগুলি ব্যতিক্রম ছুঁড়ে ফেলা উচিত। বিটিডাব্লু, মাইক্রোসফ্টের কোড বিশ্লেষণ সরঞ্জামটি আমার মতে খুব সংকীর্ণভাবে সম্পত্তি ব্যবহারের সংজ্ঞা দিচ্ছে।
"দেরি বাইন্ডিং" এর অর্থ বৈশিষ্ট্যগুলি প্রতিবিম্বের মাধ্যমে পাওয়া যায়। উদাহরণস্বরূপ সিরিয়ালাইজেবল "অ্যাট্রিবিউটটি কোনও বস্তুর বৈশিষ্ট্যগুলির মাধ্যমে সিরিয়ালাইজ / ডিজাইরিয়ালাইজ করার জন্য ব্যবহৃত হয় this এই ধরণের পরিস্থিতিতে একটি ব্যতিক্রম নিক্ষেপ করা জিনিসকে একটি বিপর্যয়কর উপায়ে ভেঙে দেয় এবং আরও দৃ .় কোড তৈরি করতে ব্যতিক্রম ব্যবহার করার ভাল উপায় নয়।
"প্রারম্ভিক বাঁধাই" এর অর্থ একটি সংকলক কর্তৃক কোনও সম্পত্তি ব্যবহার কোডে আবদ্ধ। উদাহরণস্বরূপ, যখন আপনার লেখা কিছু কোড কোনও সম্পত্তি গেটারের রেফারেন্স দেয়। এই ক্ষেত্রে ব্যতিক্রমগুলি বোঝার পরে তা ছুঁড়ে ফেলা ঠিক হবে।
অভ্যন্তরীণ বৈশিষ্ট্যযুক্ত কোনও অবজেক্টের সেই বৈশিষ্ট্যগুলির মানগুলির দ্বারা নির্ধারিত একটি রাষ্ট্র থাকে। বৈশিষ্ট্যগুলি প্রকাশ করে এমন বৈশিষ্ট্য যা অবজেক্টের অভ্যন্তরীণ অবস্থার প্রতি সচেতন এবং সংবেদনশীল তারা দেরীতে বাইন্ডিংয়ের জন্য ব্যবহার করা উচিত নয়। উদাহরণস্বরূপ, আসুন আমরা বলতে পারি যে আপনার কাছে এমন একটি অবজেক্ট রয়েছে যা অবশ্যই খোলা হবে, অ্যাক্সেস করতে হবে, তারপরে বন্ধ হবে। এক্ষেত্রে প্রথমে ওপেন না করে संपत्तीগুলি অ্যাক্সেস করার ব্যতিক্রম হওয়া উচিত। মনে করুন, এই ক্ষেত্রে, আমরা একটি ব্যতিক্রম ছুঁড়ে না ফেলেছি এবং আমরা কোনও ব্যতিক্রম ছুঁড়ে না দিয়ে কোডটিকে কোনও মান অ্যাক্সেসের অনুমতি দিই? কোডটি বুদ্ধিমানের মতো কোনও গেটারের কাছ থেকে একটি মান পেয়েছে যদিও তা খুশি মনে হবে। এখন আমরা কোডটি এমন একটি খারাপ অবস্থার মধ্যে রেখেছি যেহেতু এটি একটি খারাপ পরিস্থিতিতে called এর অর্থ কোডটি যাচাই করার জন্য অবশ্যই সম্পত্তি গেটারের কাছ থেকে পাওয়া মূল্য সম্পর্কে অনুমান করা উচিত। এভাবেই খারাপ কোড লেখা হয়।
আমার এই কোডটি ছিল যেখানে আমার কোন ব্যতিক্রম নিক্ষেপ করার বিষয়ে অনিশ্চিত ছিল।
public Person
{
public string Name { get; set; }
public boolean HasPets { get; set; }
}
public void Foo(Person person)
{
if (person.Name == null) {
throw new Exception("Name of person is null.");
// I was unsure of which exception to throw here.
}
Console.WriteLine("Name is: " + person.Name);
}
আমি মডেলটিকে নির্মাণকারীর পক্ষে যুক্তি হিসাবে জোর করে প্রথম স্থানে সম্পত্তি বাতিল হতে বাধা দিয়েছিলাম।
public Person
{
public Person(string name)
{
if (name == null) {
throw new ArgumentNullException(nameof(name));
}
Name = name;
}
public string Name { get; private set; }
public boolean HasPets { get; set; }
}
public void Foo(Person person)
{
Console.WriteLine("Name is: " + person.Name);
}