কেন "ক্যাচ" বা "অবশেষে" স্কোপগুলিতে "চেষ্টা" করে ভেরিয়েবল ঘোষিত হয় না?


139

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

try {
  String s = "test";
  // (more code...)
}
catch {
  Console.Out.WriteLine(s);  //Java fans: think "System.out.println" here instead
}

এই কোডটিতে, ক্যাচ ব্লকে s এর রেফারেন্সে একটি সংকলন-সময় ত্রুটি দেখা দেয়, কারণ s কেবলমাত্র চেষ্টা ব্লকের ফাঁকে। (জাভাতে, সংকলনের ত্রুটিটি "গুলি সমাধান করা যায় না"; সি # তে এটি "নাম 's' বর্তমান প্রসঙ্গে নেই"))

এই সমস্যার সাধারণ সমাধানটি চেষ্টা ব্লকের পরিবর্তে, চেষ্টা ব্লকের ঠিক আগে পরিবর্তকগুলি ঘোষিত করা বলে মনে হচ্ছে:

String s;
try {
  s = "test";
  // (more code...)
}
catch {
  Console.Out.WriteLine(s);  //Java fans: think "System.out.println" here instead
}

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

আমার প্রশ্ন হ'ল, এই ভাষা নকশার সিদ্ধান্তের পিছনে (জাভাতে, সি # তে, এবং / অথবা অন্য কোনও প্রয়োগযোগ্য ভাষায়) যুক্তি (গুলি) কী ছিল?

উত্তর:


171

দুটি জিনিস:

  1. সাধারণত, জাভাতে মাত্র 2 স্তরের সুযোগ থাকে: বৈশ্বিক এবং ফাংশন। তবে, চেষ্টা / ধরা একটি ব্যতিক্রম (কোনও পাং উদ্দেশ্যে নয়)। যখন কোনও ব্যতিক্রম নিক্ষেপ করা হয় এবং ব্যতিক্রম বস্তুটি তার জন্য নির্ধারিত একটি চলক পায়, সেই অবজেক্ট ভেরিয়েবলটি কেবল "ক্যাচ" বিভাগের মধ্যে পাওয়া যায় এবং ক্যাচটি সম্পূর্ণ হওয়ার সাথে সাথেই তা ধ্বংস হয়ে যায়।

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

    
    try
    {
        throw new ArgumentException("some operation that throws an exception");
        string s = "blah";
    }
    catch (e as ArgumentException)
    {  
        Console.Out.WriteLine(s);
    }

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


55

আপনি কীভাবে নিশ্চিত হতে পারেন যে আপনি আপনার ক্যাচ ব্লকের ঘোষণার অংশে পৌঁছেছেন? যদি ইনস্ট্যান্টেশন ব্যতিক্রম ছোঁড়ে?


6
তাই না? পরিবর্তনীয় ঘোষণাগুলি ব্যতিক্রম ছুঁড়ে না ফেলে।
জোশুয়া

6
সম্মত, এটি ইনস্ট্যান্টেশন যা ব্যতিক্রম ছুঁড়ে দিতে পারে।
বুখার্ড

19

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

... code ...
{
    string s = "test";
    try
    {
        // more code
    }
    catch(...)
    {
        Console.Out.WriteLine(s);
    }
}

সম্পাদনা করুন: আমি প্রতি নিয়ম অনুমান করে একটি ব্যতিক্রম আছে। নিম্নলিখিতটি বৈধ সি ++:

int f() { return 0; }

void main() 
{
    int y = 0;

    if (int x = f())
    {
        cout << x;
    }
    else
    {
        cout << x;
    }
}

X এর পরিধিটি শর্তযুক্ত, তত্কালীন ধারা এবং অন্যটি ধারা use


10

অন্য প্রত্যেকে বেসিকগুলি তুলে ধরেছে - ব্লকে যা ঘটে তা একটি ব্লকে থাকে। .NET- র ক্ষেত্রে কম্পাইলার কী মনে করছে তা যাচাই করা সহায়ক হতে পারে। উদাহরণস্বরূপ, নিম্নলিখিত চেষ্টা / ক্যাচ কোডটি ধরুন (নোট করুন যে স্ট্রিমরিডার সঠিকভাবে ব্লকের বাইরে ঘোষণা করা হয়েছে):

static void TryCatchFinally()
{
    StreamReader sr = null;
    try
    {
        sr = new StreamReader(path);
        Console.WriteLine(sr.ReadToEnd());
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
    finally
    {
        if (sr != null)
        {
            sr.Close();
        }
    }
}

এটি এমএসআইএলে নিম্নলিখিতগুলির মতো কিছু সংকলন করবে:

.method private hidebysig static void  TryCatchFinallyDispose() cil managed
{
  // Code size       53 (0x35)    
  .maxstack  2    
  .locals init ([0] class [mscorlib]System.IO.StreamReader sr,    
           [1] class [mscorlib]System.Exception ex)    
  IL_0000:  ldnull    
  IL_0001:  stloc.0    
  .try    
  {    
    .try    
    {    
      IL_0002:  ldsfld     string UsingTest.Class1::path    
      IL_0007:  newobj     instance void [mscorlib]System.IO.StreamReader::.ctor(string)    
      IL_000c:  stloc.0    
      IL_000d:  ldloc.0    
      IL_000e:  callvirt   instance string [mscorlib]System.IO.TextReader::ReadToEnd()
      IL_0013:  call       void [mscorlib]System.Console::WriteLine(string)    
      IL_0018:  leave.s    IL_0028
    }  // end .try
    catch [mscorlib]System.Exception 
    {
      IL_001a:  stloc.1
      IL_001b:  ldloc.1    
      IL_001c:  callvirt   instance string [mscorlib]System.Exception::ToString()    
      IL_0021:  call       void [mscorlib]System.Console::WriteLine(string)    
      IL_0026:  leave.s    IL_0028    
    }  // end handler    
    IL_0028:  leave.s    IL_0034    
  }  // end .try    
  finally    
  {    
    IL_002a:  ldloc.0    
    IL_002b:  brfalse.s  IL_0033    
    IL_002d:  ldloc.0    
    IL_002e:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()    
    IL_0033:  endfinally    
  }  // end handler    
  IL_0034:  ret    
} // end of method Class1::TryCatchFinallyDispose

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

সুযোগটি আপনাকে রক্ষা করে তবে আপনাকে মাঝে মাঝে এটিকে ঘিরে কাজ করতে হবে। সময়ের সাথে সাথে, আপনি এটিতে অভ্যস্ত হয়ে যান এবং এটি প্রাকৃতিক বোধ শুরু করে। সবার মতোই বলেছিলেন, ব্লকে যা ঘটে তা সেই ব্লকে থাকে। আপনি কিছু ভাগ করতে চান? আপনাকে ব্লকের বাইরে যেতে হবে ...


8

যে কোনও হারে সি ++ এ, চারপাশে ঘিরে থাকা কোঁকড়ানো ধনুর্বন্ধনী দ্বারা একটি স্বয়ংক্রিয় পরিবর্তনশীলের পরিসর সীমাবদ্ধ। কেউ কেন কোঁকড়া ধনুর্বন্ধনী বাইরে একটি চেষ্টা কীওয়ার্ড নিচে ফেলে এটি আলাদা হতে আশা করবে?


1
একমত; "}" এর অর্থ স্কোপ-এর শেষ end যাইহোক, চেষ্টা-ধরা-অবশেষে এটি অস্বাভাবিক একটি চেষ্টা ব্লকের পরে, আপনার অবশ্যই একটি ক্যাচ এবং / বা অবশেষে অবরুদ্ধ থাকতে হবে; সুতরাং, স্বাভাবিক নিয়মের ব্যতিক্রম যেখানে সম্পর্কিত ক্যাচ / অবশেষে ট্রাই ব্লকের বহনযোগ্যতা গ্রহণযোগ্য বলে মনে হতে পারে?
জন স্নাইডার

7

রেভেনস্পিন্টে নির্দেশিত মতো, প্রত্যেকেই প্রত্যাশা করা ব্লকের ভেরিয়েবলগুলি স্থানীয় হওয়ার প্রত্যাশা করে trya একটি ব্লকের পরিচয় করিয়ে দেয় এবং তাই করে catch

আপনি যদি উভয়কেই ভেরিয়েবল স্থানীয় করতে চান tryএবং catchউভয়টিকে একটি ব্লকে সংযুক্ত করার চেষ্টা করুন:

// here is some code
{
    string s;
    try
    {

        throw new Exception(":(")
    }
    catch (Exception e)
    {
        Debug.WriteLine(s);
    }
}

5

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

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


4

@ বারখার্ডের কাছে প্রশ্ন রয়েছে কেন সঠিকভাবে উত্তর দেওয়া হয়েছে তবে আমি একটি নোট হিসাবে যুক্ত করতে চেয়েছিলাম, যদিও আপনার প্রস্তাবিত সমাধানের উদাহরণটি 99.9999 +% সময় ভাল, এটি অনুশীলন নয়, এটি ব্যবহারের আগে নাল পরীক্ষা করা আরও নিরাপদ is চেষ্টা ব্লকের মধ্যে কিছু ইনস্ট্যান্টিয়েট করে, বা চেষ্টা ব্লকের আগে এটি ঘোষণার পরিবর্তে কিছুতে ভেরিয়েবলকে আরম্ভ করুন। উদাহরণ স্বরূপ:

string s = String.Empty;
try
{
    //do work
}
catch
{
   //safely access s
   Console.WriteLine(s);
}

বা:

string s;
try
{
    //do work
}
catch
{
   if (!String.IsNullOrEmpty(s))
   {
       //safely access s
       Console.WriteLine(s);
   }
}

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


4

এমসিটিএস সেলফ-পেসড ট্রেনিং কিট (পরীক্ষা 70০--5 2)) এর পাঠ ২ -তে "কীভাবে ফেলুন এবং কীভাবে ব্যতিক্রমগুলি ধরবেন " শীর্ষক বিভাগ অনুযায়ী : মাইক্রোসফ্ট ®। নেট ফ্রেমওয়ার্ক ২.০ — অ্যাপ্লিকেশন ডেভলপমেন্ট ফাউন্ডেশন , কারণটি ব্যতিক্রম ঘটেছে চেষ্টা ব্লকে পরিবর্তনশীল ঘোষণার আগে (যেমন অন্যরা ইতিমধ্যে উল্লেখ করেছে)।

25 পৃষ্ঠা থেকে উদ্ধৃতি:

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


4

প্রত্যেকে যেমন নির্দেশ করেছে, উত্তরটি বেশ "" এভাবেই ব্লকগুলি সংজ্ঞায়িত করা হয় "।

কোডটি প্রিটিটিয়ার করার জন্য কিছু প্রস্তাব রয়েছে। এআরএম দেখুন

 try (FileReader in = makeReader(), FileWriter out = makeWriter()) {
       // code using in and out
 } catch(IOException e) {
       // ...
 }

বন্ধগুলিও এটিকে সম্বোধন করার কথা।

with(FileReader in : makeReader()) with(FileWriter out : makeWriter()) {
    // code using in and out
}

আপডেট: এআরএম জাভা in এ বাস্তবায়িত হয়েছে http: //


2

আপনার সমাধান ঠিক আপনার যা করা উচিত। আপনি নিশ্চিত হতে পারবেন না যে আপনার ঘোষণাটি এমনকি চেষ্টা ব্লকে পৌঁছে গেছে, যার ফলে ক্যাচ ব্লকে আরও একটি ব্যতিক্রম ঘটবে in

এটি কেবল পৃথক স্কোপ হিসাবে কাজ করতে হবে।

try
    dim i as integer = 10 / 0 ''// Throw an exception
    dim s as string = "hi"
catch (e)
    console.writeln(s) ''// Would throw another exception, if this was allowed to compile
end try

2

ভেরিয়েবলগুলি ব্লক স্তর এবং সেই চেষ্টা বা ক্যাচ ব্লকের মধ্যে সীমাবদ্ধ। যদি একটি বিবৃতিতে একটি পরিবর্তনশীল সংজ্ঞায়িত অনুরূপ। এই পরিস্থিতি সম্পর্কে চিন্তা করুন।

try {    
    fileOpen("no real file Name");    
    String s = "GO TROJANS"; 
} catch (Exception) {   
    print(s); 
}

স্ট্রিংটি কখনই ঘোষণা করা হবে না, সুতরাং এটির উপর নির্ভর করা যায় না।


2

কারণ ট্রাই ব্লক এবং ক্যাচ ব্লক হল 2 টি আলাদা ব্লক।

নিম্নলিখিত কোডে, আপনি কী ব্লক এ সংজ্ঞায়িত ব্লক বিতে দৃশ্যমান হবে তা আশা করবেন?

{ // block A
  string s = "dude";
}

{ // block B
  Console.Out.WriteLine(s); // or printf or whatever
}

2

আপনার উদাহরণে এটি অদ্ভুত যে এটি কার্যকর হয় না, এইটিকে অনুরূপ গ্রহণ করুন:

    try
    {
         //Code 1
         String s = "1|2";
         //Code 2
    }
    catch
    {
         Console.WriteLine(s.Split('|')[1]);
    }

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

আবার এটিকে তাত্ত্বিকভাবে কেবল পৃথক সংজ্ঞা ( String s; s = "1|2";) বা কিছু শর্তের সেটকে অনুমতি দিয়ে স্থির করা যেতে পারে তবে কেবল না বলা সহজ হয়।

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

অবশেষে, আপনি যা চান তা করতে, আপনি চেষ্টা করার চেষ্টাটির চারপাশে বন্ধনীগুলির একটি সেট যুক্ত করতে পারেন। আপনি যে সুযোগ চান তা আপনাকে দেয়, যদিও এটি সামান্য পাঠযোগ্যতার জন্য ব্যয় হয় তবে খুব বেশি নয়।

{
     String s;
     try
     {
          s = "test";
          //More code
     }
     catch
     {
          Console.WriteLine(s);
     }
}

1

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

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

এছাড়াও, কোড পাঠযোগ্যতার ক্ষতি হবে। সি এর নিয়ম (এবং সি ++, জাভা এবং সি # সহ যে ভাষাগুলি এটি অনুসরণ করে) সাধারণ: ভেরিয়েবল স্কোপগুলি ব্লক অনুসরণ করে।

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


1

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

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


1

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

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


1

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


1

যেমনটি অন্যান্য ব্যবহারকারীদের দ্বারা ইঙ্গিত করা হয়েছে, কোঁকড়ানো ধনুর্বন্ধনী ধনুর্বন্ধিকাগুলি আমি জানি প্রতিটি সি স্টাইলের ভাষাতে স্কোপটিকে সংজ্ঞায়িত করে।

যদি এটি একটি সাধারণ পরিবর্তনশীল হয়, তবে কেন আপনি এটি যত্নের মধ্যে রাখবেন যে এটি কত দিন ব্যাপী থাকবে? এটি এত বড় চুক্তি নয়।

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


1

পাইথনগুলিতে তারা ক্যাচ / অবশেষে ব্লকগুলিতে দৃশ্যমান থাকে যদি তাদের ঘোষণার রেখাটি ছুঁড়ে না দেয়।


1

ব্যতিক্রমের ঘোষণার isর্ধ্বে থাকা কোনও কোডে যদি ব্যতিক্রম নিক্ষেপ করা হয় তবে কী হবে। যার অর্থ, ঘোষণাপত্রটি নিজেই এই ক্ষেত্রে খুশি ছিল না।

try {

       //doSomeWork // Exception is thrown in this line. 
       String s;
       //doRestOfTheWork

} catch (Exception) {
        //Use s;//Problem here
} finally {
        //Use s;//Problem here
}

1

সি শার্প ফটকা খেলা (15.2) যুক্তরাষ্ট্রের "একটি স্থানীয় পরিবর্তনশীল বা ধ্রুবক সুযোগ ব্লক IST একটি ব্লক ঘোষণা।"

(আপনার প্রথম উদাহরণে ট্রাই ব্লকটি হ'ল ব্লক যেখানে "গুলি" ঘোষণা করা হয়েছে)


0

আমার ধারণাটি হ'ল যেহেতু চেষ্টা ব্লকের কিছু ব্যতিক্রমকে ট্রিগার করেছিল তার নাম স্থানের বিষয়বস্তু বিশ্বাস করা যায় না - যেমন ক্যাচ ব্লকে স্ট্রিংয়ের 'গুলি' উল্লেখ করা অন্য কোনও ব্যতিক্রম ছোঁড়াবার কারণ হতে পারে।


0

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


0

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

// won't compile!
try
{
    VeryLargeArray v = new VeryLargeArray(TOO_BIG_CONSTANT); // throws OutOfMemoryException
    string s = "Help";
}
catch
{
    Console.WriteLine(s); // whoops!
}

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

সুতরাং আমরা সংকলকটির অনেক কাজ করার সমাপ্তি পেয়েছি, যা বাস্তবে খুব বেশি সুবিধা দেয় না এবং সম্ভবত লোকজনকে বিভ্রান্ত করে এবং কেন চেষ্টা করে / ধরা বিভিন্নভাবে কাজ করে তা জিজ্ঞাসা করতে তাদের নেতৃত্ব দেয়।

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

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

উদাহরণস্বরূপ আইডিস্পোজেবল অবজেক্টস সহ কীওয়ার্ডটি এতে ব্যবহার করুন :

using(Writer writer = new Writer())
{
    writer.Write("Hello");
}

সমান:

Writer writer = new Writer();
try
{        
    writer.Write("Hello");
}
finally
{
    if( writer != null)
    {
        ((IDisposable)writer).Dispose();
    }
}

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


0

স্থানীয় ভেরিয়েবলের পরিবর্তে একটি সরকারী সম্পত্তি ঘোষণা করা যেতে পারে; এটিও একটি সাইন করা ভেরিয়েবলের অন্য সম্ভাব্য ত্রুটি এড়ানো উচিত। পাবলিক স্ট্রিং S {get; সেট; }


-1

যদি অ্যাসাইনমেন্ট অপারেশন ব্যর্থ হয় তবে আপনার ক্যাচ স্টেটমেন্টটিতে অনির্ধারিত ভেরিয়েবলের নাল রেফারেন্স থাকবে।


2
এটি নিযুক্ত এটি এমনকি নালও নয় (উদাহরণ এবং স্থির ভেরিয়েবলগুলির বিপরীতে)।
টম হাটিন -

-1

সি # 3.0:

string html = new Func<string>(() =>
{
    string webpage;

    try
    {
        using(WebClient downloader = new WebClient())
        {
            webpage = downloader.DownloadString(url);
        }
    }
    catch(WebException)
    {
        Console.WriteLine("Download failed.");  
    }

    return webpage;
})();

ডব্লিউটিএফ? ডাউন-ভোট কেন? এনক্যাপসুলেশন ওওপি-র জন্য অবিচ্ছেদ্য। দেখতেও বেশ সুন্দর।
কোর

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