সি # তে, কেন চেষ্টা ব্লকের ভিতরে ভেরিয়েবলগুলি ঘোষিত হয় সুযোগের মধ্যে সীমাবদ্ধ?


23

আমি এতে ত্রুটি পরিচালনা করতে যুক্ত করতে চাই:

var firstVariable = 1;
var secondVariable = firstVariable;

নীচে সংকলন করবে না:

try
{
   var firstVariable = 1;
}
catch {}

try
{
   var secondVariable = firstVariable;
}
catch {}

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


14
try.. catchএকটি নির্দিষ্ট ধরণের কোড ব্লক এবং যতগুলি কোড ব্লক যায়, আপনি একটিতে একটি ভেরিয়েবল ঘোষণা করতে পারবেন না এবং সেই একই ভেরিয়েবলটিকে স্কোপ হিসাবে বিবেচনা করতে পারবেন না।
নীল

"একটি নির্দিষ্ট ধরণের কোড ব্লক"। নির্দিষ্টভাবে কীভাবে? ধন্যবাদ
JᴀʏMᴇᴇ

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

টিপ: নোট করুন যে (আইডিজিপোজযোগ্য) {} এবং মাত্র {using ব্যবহার একইভাবে প্রযোজ্য। আপনি যখন কোনও আইডিস্পোজেবলের সাহায্যে কোনও ব্যবহার ব্যবহার করেন, এটি সাফল্য বা ব্যর্থতা নির্বিশেষে স্বয়ংক্রিয়ভাবে সংস্থানগুলি পরিষ্কার করবে। এর ব্যতিক্রম কিছু আছে, যেমন সমস্ত ক্লাস যেমন আপনি আইডিস্পোজেবল বাস্তবায়ন আশা করেন নি ...
জুলিয়া ম্যাকগুইগান

1
: Stackoverflow, এখানে এই একই প্রশ্নে আলোচনা প্রচুর stackoverflow.com/questions/94977/...
জন স্নাইডার

উত্তর:


90

যদি আপনার কোডটি ছিল:

try
{
   MethodThatMightThrow();
   var firstVariable = 1;
}
catch {}

try
{
   var secondVariable = firstVariable;
}
catch {}

firstVariableআপনার পদ্ধতি কল ছুড়ে দিলে এখন আপনি একটি অঘোষিত ভেরিয়েবল ( ) ব্যবহার করার চেষ্টা করছেন be

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


আহ, আমি ঠিক এই পরে ছিল। আমি জানতাম এমন কিছু ভাষা বৈশিষ্ট্য রয়েছে যা আমার পক্ষে অসম্ভব বলে মনে হচ্ছে তবে আমি কোনও পরিস্থিতি নিয়ে আসতে পারিনি। অনেক ধন্যবাদ.
JᴀʏMᴇᴇ

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

3
সি # এর মতো স্থির ভাষার জন্য, সংকলনের সময় ঘোষণাটি কেবলমাত্র প্রাসঙ্গিক। সংকলক সহজেই স্কোপটিতে ঘোষণাকে সরিয়ে ফেলতে পারে। রানটাইমের সময় আরও গুরুত্বপূর্ণ সত্যটি হল ভেরিয়েবলটি আরম্ভ করা নাও হতে পারে ।
jpmc26

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

2
অঘোষিত অবিচ্ছিন্ন এবং সি # আলাদাভাবে তাদের ট্র্যাক করার মধ্যে পার্থক্য রয়েছে। এটির ঘোষিত ব্লকের বাইরে যদি আপনাকে কোনও ভেরিয়েবল ব্যবহারের অনুমতি দেওয়া হয়, তবে এর অর্থ হ'ল আপনি এটি প্রথম catchব্লকে নির্ধারণ করতে সক্ষম হবেন এবং তারপরে এটি অবশ্যই দ্বিতীয় tryব্লকে নির্ধারিত হবে ।
svick

64

আমি জানি যে এটির বেন দ্বারা ভাল উত্তর দেওয়া হয়েছে, তবে আমি পিওভির যে ধারাবাহিকতাটি সুবিধামতভাবে সরানো হয়েছিল তা সম্বোধন করতে চেয়েছিলাম। ধরে নিই যে try/catchব্লকগুলি সুযোগকে প্রভাবিত করে না, তারপরে আপনি এগুলি শেষ করবেন:

{
    // new scope here
}

try
{
   // Not new scope
}

এবং আমার কাছে এটি ক্র্যাশ করে সর্বনিম্ন বিস্ময়ের মূল নীতিতে (পোলা) কারণ আপনার এখন {এবং} তাদের পূর্ববর্তী বিষয়গুলির প্রেক্ষাপটে নির্ভর করে দ্বিগুণ দায়িত্ব পালন করছেন।

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


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

"এই জগাখিচুড়ি থেকে বেরিয়ে আসার একমাত্র উপায় হ'ল অন্য কিছু চিহ্নিতকারীকে ব্লক try/ catchব্লকগুলি নির্দিষ্ট করার জন্য " " - মানে try { { // scope } }? :)
CompuChip

@ কমপুকশিপটি {}প্রসঙ্গের উপর নির্ভর করে স্কোপ তৈরির সুযোগ হিসাবে দ্বিগুণ কর্তব্য টানবে না। try^ //no-scope ^একটি ভিন্ন চিহ্নিতকারী উদাহরণ হতে হবে।
Leliel

1
আমার মতে এটিই অনেক বেশি মৌলিক কারণ এবং "আসল" উত্তরটির কাছাকাছি।
জ্যাক এইডলি

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

21

ধারাবাহিকতা স্বার্থে, এটিকে রিফ্যাক্টরের প্রয়োজন ছাড়াই ত্রুটি পরিচালনার সাথে আমাদের কোডটি গুটিয়ে রাখতে সক্ষম হওয়া কী বোঝায়?

এর উত্তর দেওয়ার জন্য, কেবলমাত্র একটি ভেরিয়েবলের সুযোগের চেয়ে বেশি দেখার প্রয়োজন

এমনকি যদি ভেরিয়েবল সুযোগে থেকে যায়, তবে এটি অবশ্যই নির্ধারিত হবে না ।

ট্রায়াল ব্লকের পরিবর্তনশীল ঘোষণা করে - সংকলক এবং মানব পাঠকদের কাছে - যে এটি কেবলমাত্র সেই ব্লকের ভিতরে অর্থবহ। এটি প্রয়োগ করার জন্য এটি সংকলকটির পক্ষে কার্যকর।

ট্রাই ব্লকের পরে আপনি যদি ভেরিয়েবলটি স্কোপে থাকতে চান তবে আপনি এটিকে ব্লকের বাইরে ঘোষণা করতে পারেন:

var zerothVariable = 1_000_000_000_000L;
int firstVariable;

try {
    // Change checked to unchecked to allow the overflow without throwing.
    firstVariable = checked((int)zerothVariable);
}
catch (OverflowException e) {
    Console.Error.WriteLine(e.Message);
    Environment.Exit(1);
}

এটি প্রকাশ করে যে ভেরিয়েবল চেষ্টা ব্লকের বাইরে অর্থবহ হতে পারে। সংকলক এটি অনুমতি দেবে।

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

ধরুন ট্রাই ব্লকের পরে আমি ভেরিয়েবল থেকে পড়ার চেষ্টা করেছি:

Console.WriteLine(firstVariable);

এটি একটি সংকলন-সময় ত্রুটি দেবে :

CS0165 অচিহ্নযুক্ত স্থানীয় ভেরিয়েবল 'ফার্স্ট ভেরিয়েবল' এর ব্যবহার

আমি ক্যাচ ব্লকে এনভায়রনমেন্ট.এক্সিটকে ডেকেছি , তাই আমি জানি কনসোল.ব্রাইটলাইনকে কল করার আগে ভেরিয়েবলটি বরাদ্দ করা হয়েছে। সংকলক এটি অনুমান করে না।

সংকলকটি এত কঠোর কেন?

আমি এটিও করতে পারি না:

int n;

try {
    n = 10; // I know this won't throw an IOException.
}
catch (IOException) {
}

Console.WriteLine(n);

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

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

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

আপনি ভেরিয়েবলটি সমস্ত কোড পাথের মাধ্যমে নির্ধারিত হয়েছে তা নিশ্চিত করতে পারেন।

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

var n = 0; // But is this meaningful, or just covering a bug?

try {
    n = 10;
}
catch (IOException) {
}

Console.WriteLine(n);

বা:

int n;

try {
    n = 10;
}
catch (IOException) {
    n = 0; // But is this meaningful, or just covering a bug?
}

Console.WriteLine(n);

যারা সংকলন। তবে কেবলমাত্র এমন কিছু করা ভাল যদি আপনি প্রদত্ত ডিফল্ট মানটি বোঝায় * এবং সঠিক আচরণ করে and

মনে রাখবেন, এই দ্বিতীয় ক্ষেত্রে যেখানে আপনি চেষ্টা ব্লক এবং সমস্ত ক্যাপ ব্লকে ভেরিয়েবল নির্ধারণ করেন, যদিও আপনি চেষ্টা করার পরে ভেরিয়েবলটি পড়তে পারেন, আপনি এখনও একটি সংযুক্ত finallyব্লকের ভিতরে ভেরিয়েবলটি পড়তে পারবেন না , কারণ আমরা প্রায়শই যা ভাবি তার থেকে বেশি পরিস্থিতিতে মৃত্যুদণ্ড কার্যকর করা একটি প্রচেষ্টা অবিরত রাখতে পারে

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

আপনি এটিকে এমন কোড পাথ করতে পারেন যেখানে ভেরিয়েবল নির্ধারিত নয় একটি ব্যতিক্রম (বা ফিরে) নিক্ষেপ করুন।

যদি আপনি কিছু ক্রিয়া সম্পাদন করার পরিকল্পনা করেন (যেমন লগিং) এবং ব্যতিক্রমটি পুনর্বিবেচনা বা অন্য ব্যতিক্রম নিক্ষেপ করেন এবং ভেরিয়েবলটি নির্ধারিত না হয় এমন কোনও ক্যাচ ক্লাউজে এটি ঘটে থাকে, তবে সংকলকটি জানতে পারবে যে ভেরিয়েবলটি নির্ধারিত হয়েছে:

int n;

try {
    n = 10;
}
catch (IOException e) {
    Console.Error.WriteLine(e.Message);
    throw;
}

Console.WriteLine(n);

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

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

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

আপনি সত্যিই করতে পারেন কোডটি রিফ্যাক্টর চান।

আপনার উদাহরণে, আপনি পরিচয় করিয়ে দিন firstVariableএবংsecondVariable চেষ্টা করুন ব্লকগুলি। যেমনটি আমি বলেছি, চেষ্টা করা ব্লকগুলিতে তাদের নির্ধারিত হওয়ার আগে আপনি সেগুলি সংজ্ঞায়িত করতে পারেন যাতে তারা পরবর্তী সময়ে সুযোগে থাকবে এবং আপনি সর্বদা নির্ধারিত হয়ে গেছে তা নিশ্চিত করে আপনি তাদের কাছ থেকে পড়তে পারবেন এমন সংকলকটিকে সন্তুষ্ট / চালিত করতে পারেন।

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

প্রথমত, (এবং হওয়া উচিত) আপনি কি সেখানে ত্রুটিটি পরিচালনা করতে পারেন? ব্যতিক্রম হ্যান্ডলিংয়ের অন্যতম কারণ হ'ল ত্রুটিগুলি যেখানে তারা কার্যকরভাবে পরিচালনা করতে পারে তা পরিচালনা করা সহজ করে , এমনকি যেখানে এটি ঘটে তার কাছাকাছি না হলেও।

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

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

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

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

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

// In real life, this should be named more descriptively.
private static (int firstValue, int secondValue) GetFirstAndSecondValues()
{
    try {
        // This code is contrived. The idea here is that obtaining the values
        // could actually fail, and throw a SomeSpecificException.
        var firstVariable = 1;
        var secondVariable = firstVariable;
        return (firstVariable, secondVariable);
    }
    catch (SomeSpecificException e) {
        Console.Error.WriteLine(e.Message);
        Environment.Exit(1);
        throw new InvalidOperationException(); // unreachable
    }
}

// ...and of course so should this.
internal static void MethodThatUsesTheValues()
{
    var (firstVariable, secondVariable) = GetFirstAndSecondValues();

    // Code that does something with them...
}

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

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

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

উপসংহার: ব্যাপ্তি চিত্রের কেবল একটি অংশ।

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


"আপনি যখন ক্যাচ ক্লজ সহ একটি ট্রাই ব্লকে কোড লিখবেন, আপনি সংকলক এবং যে কোনও মানব পাঠক উভয়কেই বলছেন যে এটির মতো আচরণ করা উচিত এটি সমস্ত চালাতে না পারে" " সংকলকটি যা যত্ন করে তা হ'ল পূর্ববর্তী বিবৃতিগুলি ব্যতিক্রম ছুঁড়ে ফেললেও নিয়ন্ত্রণ পরবর্তী বিবৃতিগুলিতে পৌঁছতে পারে। সংকলকটি সাধারণত ধরে নেয় যে একটি বিবৃতি যদি ব্যতিক্রম ছুঁড়ে ফেলে, তবে পরবর্তী বিবৃতি কার্যকর করা হবে না, সুতরাং একটি নিরীক্ষিত ভেরিয়েবলটি পড়বে না। একটি 'ক্যাচ' যুক্ত করা নিয়ন্ত্রণকে পরবর্তী বিবৃতিগুলিতে পৌঁছানোর অনুমতি দেবে - ট্রাই ব্লকটিতে নিক্ষেপ করা কোডটি কিনা তা নয়, এটি গুরুত্বপূর্ণ catch
পিট কির্খাম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.