ম্যাজিক মান ফিরিয়ে দিন, ব্যতিক্রম নিক্ষেপ করবেন বা ব্যর্থতায় মিথ্যা ফিরবেন?


83

আমি মাঝে মাঝে ক্লাস লাইব্রেরির জন্য এমন কোনও পদ্ধতি বা সম্পত্তি লিখতে থাকি যার জন্য সত্যিকারের উত্তর না পাওয়া ব্যতিক্রমী নয়, তবে ব্যর্থতা। কিছু নির্ধারণ করা যায় না, পাওয়া যায় না, পাওয়া যায় না, বর্তমানে সম্ভব নয় বা আরও কোনও ডেটা উপলব্ধ নেই।

আমি মনে করি যে সি # 4 এ ব্যর্থতা নির্দেশ করার জন্য তুলনামূলকভাবে ব্যতিক্রমী পরিস্থিতিটির পক্ষে সম্ভাব্য তিনটি সমাধান রয়েছে :

  • এমন ম্যাজিক মান ফিরিয়ে দিন যার অন্যথায় কোনও অর্থ নেই (যেমন nullএবং -1);
  • একটি ব্যতিক্রম নিক্ষেপ (যেমন KeyNotFoundException);
  • ফিরে falseআসুন এবং একটি outপ্যারামিটারে প্রকৃত রিটার্ন মান সরবরাহ করুন (যেমন Dictionary<,>.TryGetValue)।

সুতরাং প্রশ্নগুলি: কোন ব্যতিক্রমী পরিস্থিতিতে আমার একটি ব্যতিক্রম ছুঁড়ে ফেলা উচিত? এবং যদি আমার নিক্ষেপ করা উচিত নয়: কখন প্যারামিটার Try*দিয়ে কোনও পদ্ধতি প্রয়োগের উপরে কোনও ম্যাজিক মান ফিরিয়ে দেওয়া হচ্ছেout ? (আমার কাছে outপ্যারামিটারটি নোংরা বলে মনে হচ্ছে এবং এটি সঠিকভাবে ব্যবহার করা আরও বেশি কাজ))

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


.NET ফ্রেমওয়ার্ক বেস ক্লাস লাইব্রেরিতে, তিনটি পদ্ধতিই ব্যবহৃত হয়:

  • একটি যাদু মান ফেরান যা অন্যথায় কোন অর্থ নেই:
  • একটি ব্যতিক্রম নিক্ষেপ:
    • Dictionary<,>.Item কীনটফাউন্ডএক্সেপশন নিক্ষেপ করে,
    • Double.Parseফর্ম্যাট এক্সসেপশন নিক্ষেপ; অথবা
  • ফিরে falseআসুন এবং একটি outপ্যারামিটারে আসল রিটার্ন মান প্রদান করুন :

মনে রাখবেন যে Hashtableসময়ে # # তে জেনারিক ছিল না এমন সময়ে এটি তৈরি হয়েছিল objectএবং এটি nullযাদু মান হিসাবে ফিরে আসতে পারে। তবে জেনেরিকের সাথে ব্যতিক্রমগুলি ব্যবহৃত হয় Dictionary<,>এবং শুরুতে এটি হয় নি TryGetValue। স্পষ্টত অন্তর্দৃষ্টি পরিবর্তন।

একথাও ঠিক যে, Item- TryGetValueParse- TryParseদ্বৈত একটি কারণ জন্য আছে, তাই আমি অনুমান অ ব্যতিক্রমী ব্যর্থতা ব্যতিক্রম নিক্ষেপ সি # 4 হয় নি । যাইহোক, Try*পদ্ধতিগুলি সর্বদা বিদ্যমান ছিল না, এমনকি Dictionary<,>.Itemবিদ্যমান ছিল।


6
"ব্যতিক্রমগুলি বাগগুলি বোঝায়"। অ-প্রতিরোধী আইটেমটির জন্য অভিধান জিজ্ঞাসা করা একটি বাগ; যখন কোনও স্ট্রিম ব্যবহার করবেন তখনই কোনও EOF যখন ঘটে তখন ডেটা পড়তে স্ট্রিমকে জিজ্ঞাসা করা। (এটি দীর্ঘ একটি সুন্দর বিন্যাসিত উত্তরটি সংক্ষিপ্ত করে আমি জমা দেওয়ার কোনও সুযোগ
পাইনি

6
এটি এমন নয় যে আমি মনে করি আপনার প্রশ্নটি খুব বিস্তৃত, এটি কোনও গঠনমূলক প্রশ্ন নয়। উত্তরগুলি ইতিমধ্যে প্রদর্শিত হওয়ায় কোনও আধ্যাত্মিক উত্তর নেই।
জর্জ স্টিকার 21

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

3
@ ভার্টলিংক: জর্জ একটি সম্প্রদায়ের দ্বারা নির্বাচিত মডারেটর যিনি স্ট্যাক ওভারফ্লো রক্ষণাবেক্ষণে সহায়তা করার জন্য তার অনেক সময় স্বেচ্ছাসেবক হন। কেন তিনি প্রশ্নটি বন্ধ করে দিয়েছিলেন, এবং এফএকিউ তাকে সমর্থন করে।
এরিক জে।

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

উত্তর:


56

আমি মনে করি না যে আপনার উদাহরণগুলি সত্যই সমান। তিনটি স্বতন্ত্র গোষ্ঠী রয়েছে যার প্রতিটি এর আচরণের জন্য নিজস্ব যুক্তিযুক্ত।

  1. ম্যাজিক মান হ'ল একটি ভাল বিকল্প যখন "যখন অবধি" শর্ত থাকে StreamReader.Readবা যখন এমন কোনও মান ব্যবহার করার মতো সহজ থাকে যা কখনই বৈধ উত্তর হতে পারে না (-1 এর জন্য IndexOf)।
  2. যখন ফাংশনটির শব্দার্থক শব্দটি কলকারী নিশ্চিত যে এটি কাজ করবে তা নিশ্চিত হলে ব্যতিক্রম ছুঁড়ে। এই ক্ষেত্রে একটি অ-বিদ্যমান কী বা খারাপ ডাবল ফর্ম্যাট সত্যই ব্যতিক্রমী।
  3. কোনও আউট প্যারামিটার ব্যবহার করুন এবং অপারেশন সম্ভব কিনা তা যদি শব্দার্থবিজ্ঞানের তদন্ত করতে হয় তবে একটি বিল ফিরিয়ে দিন।

আপনার দেওয়া উদাহরণগুলি 2 এবং 3 কেসের ক্ষেত্রে পুরোপুরি স্পষ্ট the যাদু মানগুলির জন্য, এটি যুক্তিযুক্ত হতে পারে যদি এটি কোনও ক্ষেত্রেই ভাল ডিজাইনের সিদ্ধান্ত হয় বা না হয়।

NaNদ্বারা ফিরে Math.Sqrtএকটি বিশেষ ক্ষেত্রে দেখা যায় - এটা ফ্লোটিং পয়েন্ট মান অনুসরণ করে।


10
সংখ্যা 1 এর সাথে একমত নন Mag যাদু মানগুলি কখনই একটি ভাল বিকল্প হয় না কারণ ম্যাজিক মানটির তাত্পর্য জানতে পরবর্তী কোডার প্রয়োজন। তারা পাঠযোগ্যতাকেও আহত করে। আমি এমন কোনও উদাহরণের কথা ভাবতে পারি না যেখানে চেষ্টা প্যাটার্নের চেয়ে কোনও যাদু মানের ব্যবহার আরও ভাল।
0b101010

1
তবে Either<TLeft, TRight>মোনাডের কী হবে?
সারা

2
@ 0b101010: কীভাবে স্ট্রিমরিডার.ড্রেড নিরাপদে ফিরে আসতে পারে -1 ... তা দেখার জন্য কিছুটা সময় ব্যয় করেছেন
জোরমোরো

33

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

একটি যাদু মান এখনও ডকুমেন্টেশন পড়া এবং সম্ভবত constমান ডিকোড কিছু টেবিল রেফারেন্স প্রয়োজন । আপনি যেটিকে ব্যতিক্রমী ঘটনা বলছেন তার জন্য কমপক্ষে এতে ব্যতিক্রমের ওভারহেড নেই।

এজন্য outপ্যারামিটারগুলি মাঝে মাঝে ভ্রূণুভূত হওয়া সত্ত্বেও আমি Try...সিন্টেক্স সহ সেই পদ্ধতিটি পছন্দ করি । এটি ক্যানোনিকাল। নেট এবং সি # সিনট্যাক্স। আপনি এপিআই এর ব্যবহারকারীর সাথে কথা বলছেন যে ফলাফলটি ব্যবহারের আগে তাদের ফেরতের মানটি পরীক্ষা করতে হবে। আপনি outএকটি সহায়ক ত্রুটি বার্তা সহ একটি দ্বিতীয় প্যারামিটারও অন্তর্ভুক্ত করতে পারেন , যা আবার ডিবাগিংয়ে সহায়তা করে। এজন্য আমি প্যারামিটার সমাধান Try...সহ ভোট দিয়েছি out

আরেকটি বিকল্প হ'ল একটি বিশেষ "ফলাফল" অবজেক্ট ফিরিয়ে দেওয়া, যদিও আমি এটি অনেক বেশি ক্লান্তিকর বলে মনে করি:

interface IMyResult
{
    bool Success { get; }
    // Only access this if Success is true
    MyOtherClass Result { get; }
    // Only access this if Success is false
    string ErrorMessage { get; }
}

তারপরে আপনার ফাংশনটি সঠিক দেখাচ্ছে কারণ এতে কেবল ইনপুট পরামিতি রয়েছে এবং এটি কেবল একটি জিনিস ফেরত দেয়। এটি কেবল যে এটি ফিরে আসে তা হ'ল এক ধরণের টিপল।

আসলে, আপনি যদি সেই ধরণের জিনিসটিতে থাকেন তবে আপনি নতুন Tuple<>নেট ক্লাসগুলি ব্যবহার করতে পারেন যা । নেট 4 এ প্রবর্তিত হয়েছিল Pers ব্যক্তিগতভাবে আমি এ বিষয়টি পছন্দ করি না যে প্রতিটি ক্ষেত্রের অর্থ কম স্পষ্ট হয় কারণ আমি দিতে পারি না Item1এবং Item2দরকারী নাম।


3
ব্যক্তিগতভাবে, আমি প্রায়শই আপনার IMyResultকারণের মতো ফলাফলের ধারকটি ব্যবহার করি কেবলমাত্র trueবা falseফলাফলের মানের চেয়ে আরও জটিল ফলাফলের সাথে যোগাযোগ করা সম্ভব । Try*()স্ট্রিং থেকে ইন রূপান্তরের মতো সাধারণ স্টাফগুলির জন্য কেবল কার্যকর।
এটি.আম

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

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

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

2
এটি জাভাতে চেক করা ব্যতিক্রমগুলির চেয়ে আরও ক্লান্তিকর উপায়ে সি # তে চেক করা ব্যতিক্রমগুলি পুনরায় উদ্ভাবন করছে।
শীতের

17

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

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

সংক্ষিপ্ত উত্তর

আপনি বেশ দ্রুততর পদ্ধতিগুলি ডিজাইন করার সময় এবং অপ্রত্যাশিত পুনরায় ব্যবহারের সম্ভাবনা আশা করা ব্যতীত আপনার অন্ত্রের অনুভূতিগুলি অনুসরণ করুন।

দীর্ঘ উত্তর

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

  • থাম্বের নিয়ম হিসাবে, আশা করুন যে একটি ব্যতিক্রম ছোঁড়া নিয়মিত প্রত্যাবর্তনের চেয়ে 200x ধীর হয় (বাস্তবে, এর মধ্যে একটি উল্লেখযোগ্য বৈকল্পিক রয়েছে)।

  • থাম্বের অন্য নিয়ম হিসাবে, একটি ব্যতিক্রম নিক্ষেপ করা প্রায়শই যাদু মানগুলির ক্রুডেস্টের সাথে তুলনা করে অনেক ক্লিনার কোডকে মঞ্জুরি দিতে পারে, কারণ আপনি প্রোগ্রামারটির উপর নির্ভর করে ত্রুটি কোডটিকে অন্য একটি ত্রুটি কোডের সাথে অনুবাদ করেন না, কারণ এটি ক্লায়েন্ট কোডের একাধিক স্তরগুলির দিকে ভ্রমণ করে একটি বিন্দু যেখানে এটি নিয়মিত এবং পর্যাপ্ত উপায়ে পরিচালনা করার জন্য যথেষ্ট প্রসঙ্গ রয়েছে context (বিশেষ ক্ষেত্রে: nullঅন্য যাদু মানগুলির তুলনায় এখানে আরও ভাল দামের ঝোঁক থাকে কারণ NullReferenceExceptionকিছু ত্রুটির ক্ষেত্রে স্বয়ংক্রিয়ভাবে নিজেকে অনুবাদ করার প্রবণতার কারণে সাধারণত ত্রুটিগুলির উত্সের খুব কাছাকাছি নয়, সাধারণত, তবে সবসময় নয় not )

তাহলে পাঠ কি?

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

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

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

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

আপনি Dictionary<,>.Itemআলগাভাবে কথা বলার পরে, নেট .1 1.1 এবং .NET 2.0 এর মধ্যে ফেরা nullমানগুলিতে পরিবর্তিত হয়ে এর দুর্দান্ত উদাহরণটি তালিকাভুক্ত করেন KeyNotFoundException(কেবলমাত্র যদি আপনি এর Hashtable.Itemব্যবহারিক অ-জেনেরিক অগ্রদূত হিসাবে বিবেচনা করতে চান তবেই )। এই "পরিবর্তন" এর কারণটি এখানে আগ্রহ ছাড়াই নেই। মান ধরণের পারফরম্যান্স অপ্টিমাইজেশন (আর বক্সিং নয়) আসল যাদু মানকে ( null) একটি অ-বিকল্প হিসাবে তৈরি করেছে; outপ্যারামিটারগুলি পারফরম্যান্স ব্যয়ের একটি ছোট্ট অংশ আনবে। এই পরবর্তী কর্মক্ষমতা বিবেচনাটি একটি নিক্ষেপ করার ওভারহেডের সাথে তুলনায় সম্পূর্ণ নগণ্যKeyNotFoundException , তবে ব্যতিক্রমের নকশাটি এখানে আরও উন্নত। কেন?

  • রেফ / আউট প্যারামিটারগুলি প্রতিবার ব্যয় করে, কেবলমাত্র "ব্যর্থতা" ক্ষেত্রে নয়
  • যে কেউ যত্ন Containsকরে তা সূচককে কল করার আগে কল করতে পারে এবং এই প্যাটার্নটি সম্পূর্ণ প্রাকৃতিকভাবে পড়ে। যদি কোনও বিকাশকারী ফোন করতে চান তবে কল করতে ভুলে যায় Contains, কোনও পারফরম্যান্সের সমস্যা ক্রাইপ করতে পারে না; KeyNotFoundExceptionলক্ষ্য করা এবং স্থির করতে যথেষ্ট জোরে।

আমি মনে করি 200x ব্যতিক্রম জন্য perf সম্পর্কে আশাবাদী হচ্ছে ... দেখুন blogs.msdn.com/b/cbrumme/archive/2003/10/01/51524.aspx শুধু মন্তব্য করার আগে "পারফরমেন্স এবং প্রবণতা" বিভাগে।
gbjbaanb

@gbjbaanb - ভাল, সম্ভবত। এই নিবন্ধটি পুরোপুরি আলাদা বলপার্ক নয় এমন বিষয়টি আলোচনার জন্য 1% ব্যর্থতার হার ব্যবহার করে। আমার নিজস্ব চিন্তাভাবনা এবং অস্পষ্টভাবে মনে রাখা পরিমাপ টেবিল-প্রয়োগকৃত সি ++ এর প্রেক্ষাপট থেকে হবে ( এই প্রতিবেদনের বিভাগ 5.4.1.2 দেখুন , যেখানে একটি সমস্যা হ'ল এর ধরণের প্রথম ব্যতিক্রম সম্ভবত পৃষ্ঠা ত্রুটি দিয়ে শুরু হবে (কঠোর এবং পরিবর্তনশীল তবে এক বার ওভারহেডকে কৃপণ করে তোলা) But তবে আমি নেট নেট 4 নিয়ে একটি পরীক্ষা পোস্ট করব এবং সম্ভবত এই বলপার্কের মানটি সামঞ্জস্য করব I আমি ইতিমধ্যে বৈকল্পিকতার উপর জোর দিয়েছি
জিরকা হানিকা

সুত্র / আউট পরামিতি জন্য খরচ হয় যে উচ্চ তারপর? তা কেমন করে? এবং Containsকোনও সূচককে কল দেওয়ার আগে কল করা এমন একটি রেসের শর্ত সৃষ্টি করতে পারে যা উপস্থিত থাকতে হবে না TryGetValue
ড্যানিয়েল এএ পেলসমেকার

@gbjbaanb - পরীক্ষা শেষ হয়েছে। আমি লিনাক্সে অলস এবং মনো মনো ব্যবহার করেছিলাম। ব্যতিক্রম আমাকে 3 সেকেন্ডের মধ্যে 3 563000 নিক্ষেপ করেছে। রিটার্নস আমাকে 3 সেকেন্ডের মধ্যে 10900000 ডলার দেয় gave এটি 1:20, এমনকি 1: 200 নয়। আমি এখনও আরও বাস্তববাদী কোডের জন্য 1: 100+ চিন্তা করার পরামর্শ দিচ্ছি। (আউট প্যারাম ভেরিয়েন্ট হিসাবে, যেমনটি আমি পূর্বাভাস দিয়েছিলাম, নগণ্য ব্যয় হয়েছিল - আমি আসলে সন্দেহ করি যে
চিঠিটি

@ ভার্টলিংক - সাধারণভাবে থ্রেড সুরক্ষার সাথে একমত হয়েছে তবে আপনি .NET 4 নির্দিষ্ট করে উল্লেখ করেছেন যে, ConcurrentDictionaryমাল্টি Dictionaryথ্রেডেড অ্যাক্সেসের জন্য এবং সর্বোত্তম পারফরম্যান্সের জন্য একক থ্রেডেড অ্যাক্সেসের জন্য ব্যবহার করুন। অর্থাৎ, `` সমন্বিতain ব্যবহার না করা এই বিশেষ Dictionaryশ্রেণীর সাথে কোড থ্রেডকে নিরাপদ করে না ।
জিরকা হানিকা

10

ব্যর্থতা নির্দেশ করার জন্য তুলনামূলক অ-ব্যতিক্রমী পরিস্থিতিতে সবচেয়ে ভাল কাজটি কী এবং কেন?

আপনার ব্যর্থতা দেওয়া উচিত নয়।

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

এর জন্য আর একটি কৌশল হ'ল KeyNotFoundসংবেদন। প্রায় প্রতিটি কোডবেসে আমি ৩.০ থেকে কাজ করেছি, এই এক্সটেনশন পদ্ধতির মতো কিছু রয়েছে:

public static class DictionaryExtensions {
    public static V GetValue<K, V>(this IDictionary<K, V> arg, K key, Func<K,V> ifNotFound) {
        if (!arg.ContainsKey(key)) {
            return ifNotFound(key);
        }

        return arg[key];
    }
}

এটির জন্য কোনও আসল ব্যর্থতা মোড নেই। ConcurrentDictionaryঅনুরূপ GetOrAddঅন্তর্নির্মিত আছে

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

দ্বিতীয় বিকল্পটি যথেষ্ট ভাল যখন আপনার ব্যবহারকারী বোবা কিছু করেন। আপনাকে ভুল ফর্ম্যাটের সাথে একটি স্ট্রিং দেয়, 42 শে ডিসেম্বর তারিখটি সেট করার চেষ্টা করে ... এমন কিছু যা আপনি চান যে পরীক্ষাগুলির সময় জিনিসগুলি দ্রুত এবং দর্শনীয়ভাবে ফুটিয়ে তুলতে পারে যাতে খারাপ কোডটি চিহ্নিত করা এবং ঠিক করা যায়।

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

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


7
পোষা প্রাণীকে এখানে outউপস্থাপন করুন: পার্শ্ব প্রতিক্রিয়াগুলি প্রকাশের ক্ষেত্রে প্যারামিটারগুলি সম্পূর্ণ orthogonal। একটি refপ্যারামিটার পরিবর্তন করা একটি পার্শ্ব প্রতিক্রিয়া, এবং কোনও ইনপুট প্যারামিটারের মাধ্যমে আপনি যে বস্তুর অবস্থার মধ্য দিয়ে যাচ্ছেন তা সংশোধন করা একটি পার্শ্ব প্রতিক্রিয়া, তবে একটি outপরামিতি একটি ফাংশনকে একাধিক মান ফেরত দেওয়ার কেবল একটি বিশ্রী উপায়। কোনও পার্শ্ব প্রতিক্রিয়া নেই, কেবল একাধিক রিটার্ন মান।
স্কট হুইটলক

আমি বললাম ঝোঁক কারণ লোকেরা কীভাবে তাদের ব্যবহার এর। আপনি যেমন বলছেন, সেগুলি কেবল একাধিক ফেরতের মান।
টেলাস্টিন

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

একটি পৃথক বৈধতা পদ্ধতি রেখে @ ভার্টলিঙ্ক ইউআই-কে এটি জমা দেওয়ার আগে তাদের যথাযথ বার্তাগুলি সরবরাহ করা আপনার যেভাবেই দরকার ।
টেলাস্টিন

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

2

সর্বদা একটি ব্যতিক্রম নিক্ষেপ পছন্দ। এটি ব্যর্থ হতে পারে এমন সমস্ত ক্রিয়াকলাপগুলির মধ্যে একটি অভিন্ন ইন্টারফেস পেয়েছে এবং এটি ব্যর্থতাটিকে যতটা সম্ভব শোরগোলের ইঙ্গিত দেয় very খুব আকাঙ্ক্ষিত সম্পত্তি।

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


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

1
এটি আরও বিশেষজ্ঞের প্রয়োজন, সাধারণ ক্ষেত্রে নয়।
ডেড এমএমজি

2
তাই আপনি বলতে. তবে আপনি "সর্বদা" শব্দটি ব্যবহার করেছেন। :)
রবার্ট হার্ভে

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

ব্যতিক্রম ব্যয়বহুল নয়। গভীরভাবে নিক্ষিপ্ত ব্যতিক্রমগুলি ধরা ব্যয়বহুল হতে পারে কারণ সিস্টেমটিকে স্ট্যাকটি নিকটতম সমালোচনামূলক বিন্দুতে উন্মুক্ত করতে হবে। তবে এই "ব্যয়বহুল" তুলনামূলকভাবে ক্ষুদ্র এবং শক্ত ঘাসযুক্ত লুপগুলিতেও ভয় পাওয়া উচিত নয়।
ম্যাথু হোয়াইট

2

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

এই সমাধানটি historicalতিহাসিক কারণে বা পারফরম্যান্সের কারণে ব্যবহার করা যেতে পারে তবে অন্যথায় এড়ানো উচিত।

এটি দুটি সাধারণ কেস ছেড়ে দেয়: তদন্ত বা ব্যতিক্রম।

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

উদাহরণ:

আপনি প্রদত্ত পথ থেকে একটি ফাইল তৈরি করতে চান।

এই পথটি ফাইল তৈরি বা লেখার জন্য বৈধ কিনা তা আগে থেকেই মূল্যায়নের জন্য আপনার ফাইল অবজেক্টটি ব্যবহার করা উচিত।

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

অপ্রত্যাশিত ব্যর্থতা (একটি ব্যতিক্রম দ্বারা সংকেতিত) পরিচালনা করা এবং শর্তগুলি আগে থেকেই অপারেশনের জন্য সঠিক কিনা তা পরীক্ষা করা (প্রোবিং) সাধারণত অন্যরকম কাঠামোগতভাবে গঠন করা হবে এবং তাই বিভিন্ন পদ্ধতি ব্যবহার করা উচিত।


0

আমি মনে করি যে Tryপ্যাটার্নটি সেরা পছন্দ, যখন কোড কেবল যা ঘটেছিল তা নির্দেশ করে। আমি পরমকে ঘৃণা করি এবং নুলযোগ্য বস্তুর মতো। আমি নিম্নলিখিত ক্লাস তৈরি করেছি

public sealed class Bag<TValue>
{
    public Bag(TValue value, bool hasValue = true)
    {
        HasValue = hasValue;
        Value = value;
    }

    public static Bag<TValue> Empty
    {
        get { return new Bag<TValue>(default(TValue), false); }
    }

    public bool HasValue { get; private set; }
    public TValue Value { get; private set; }
}

সুতরাং আমি নিম্নলিখিত কোড লিখতে পারেন

    public static Bag<XElement> GetXElement(this XElement element, string elementName)
    {
        try
        {
            XElement result = element.Element(elementName);
            return result == null
                       ? Bag<XElement>.Empty
                       : new Bag<XElement>(result);
        }
        catch (Exception)
        {
            return Bag<XElement>.Empty;
        }
    }

শোধনযোগ্য দেখতে দেখতে কেবল মূল্য ধরণের জন্য নয়

আরেকটি উদাহরণ

    public static Bag<string> TryParseString(this XElement element, string attributeName)
    {
        Bag<string> attributeResult = GetString(element, attributeName);
        if (attributeResult.HasValue)
        {
            return new Bag<string>(attributeResult.Value);
        }
        return Bag<string>.Empty;
    }

    private static Bag<string> GetString(XElement element, string attributeName)
    {
        try
        {
            string result = element.GetAttribute(attributeName).Value;
            return new Bag<string>(result);
        }
        catch (Exception)
        {
            return Bag<string>.Empty;
        }
    }

3
try catchআপনি যদি GetXElement()অনেকবার কল করে এবং ব্যর্থ হন তবে আপনার পারফরম্যান্সকে ধ্বংস করে দেবে ।
রবার্ট হার্ভে

কিছু সময় এটা কোন ব্যাপার না। ব্যাগ কলটি একবার দেখুন। আপনার পর্যবেক্ষণের জন্য ধন্যবাদ

আপনার ব্যাগ <টি> CLAs System.Nullable প্রায় অভিন্ন <টি> ওরফে "nullable বস্তুর"
aeroson

হ্যাঁ, public struct Nullable<T> where T : structএকটি সীমাবদ্ধতার মধ্যে প্রায় মূল পার্থক্য। বিটিডব্লিউর
জিসার্জ

0

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

    public static Lazy<TValue> GetValue<TValue, TKey>(
        this IDictionary<TKey, TValue> dictionary,
        TKey key)
    {
        TValue retVal;
        if (dictionary.TryGetValue(key, out retVal))
        {
            var retValRef = retVal;
            var lazy = new Lazy<TValue>(() => retValRef);
            retVal = lazy.Value;
            return lazy;
        }

        return new Lazy<TValue>(() => default(TValue));
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.