なぜな変数で宣言された"チャレンジする"という"範囲"をキャッチ"や"最後に"?

StackOverflow https://stackoverflow.com/questions/94977

質問

クライアントまで、フルのC#、Java(およびその他の言語)"変数の宣言された"チャレンジする"という"ブロックしない範囲に対応する"キャッチ"や"最後に"ブロックとなります。例えば、次のコードなコンパイル:

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

このコードは、コンパイル時にエラーが発生したの基準をcatchブロックでs"は範囲は、tryブロックです。(Javaのコンパイルエラーは"s解決できなか";クライアントまで、フルのC#での"名前"s'が存在しないと現在のコンテキスト".)

一般課題のようにする代わりに変数を宣言する直前には、tryブロックではなく、内をtryブロック:

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

しかし、少なくとも、(1)このよう無骨溶液とともに、(2)その結果としての変数をより大きな範囲のプログラマ用(全体の残りの方法ではなく、コンテキストのtry-catch-では最後に).

私の質問は、何のために理由の背景にあるこの言語でデザイン決定(Java、C#ソースコードおよび/またはその他適用される言語)?

役に立ちましたか?

解決

は二つのことをやろうとしてい

  1. 一般に、Javaばかりの2レベルの対象範囲:グローバル機能です。でも、try/catchでは例外あり(無punがあります。場合例外がスローされる例外オブジェクトを取得する変数において与えられていると、そのオブジェクト変数は以内に"キャッチ"の部分が破壊されて、チが完了します。

  2. (と).きだが、tryブロックは、例外がスローされます。なっていることがあり前の変数を宣言しています。そのためには不可能であるなどの変数を使用することはできませんcatch/最後に提供しています。考え、以下の場合は、スコープがご提案:

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

このときの問題に達している場合の例外ハンドラのsされている宣言しています。この漁獲物として扱う例外的な状況とfinallys 必要 を実行し、安全宣言はこの問題のコンパイル時により行います。

他のヒント

どうすればされている場合、到達の宣言におcatchブロック?どの場合、インスタンス化する例外?

伝統的には、Cスタイルの言語とその内部に巻きブレース滞在中に巻きブレース.私の生涯の可変が広範囲はどうなるのだろうかunintuitiveできます。きを実現したいものを封入し、try/catch/finallyブロック内の別のレベルのブレース.例えば

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

編集:思毎ル しています。以下は有効なC++:

int f() { return 0; }

void main() 
{
    int y = 0;

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

の範囲の条件の条項にも提供しています。

みなさんのきっかけをつくったのが、の基礎--ここではブロック約定通りに履行されるブロックです。ものです。網(ネット)と、それをするのに役立つかもしれない"そのコンパイラは考えられる現象が起きている。例えば、以下のtry/catchコード(こStreamReader宣言され、明るく、正しく、外部のブロック):

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();
        }
    }
}

このコンパイルにも以下のようにMSIL:

.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

してください。MSILを尊重し、ブロック--彼らは本質的に一部基礎コード生成時のコンパイルあるいはC#.の範囲だけでなく、ハード-セットのC#仕様で、CLR、CLSです。

の範囲を保護すが、いまいであるといわれている。時間を、もしれませんが、慣れれやすいるという感覚を持つことが自然になります。いとどうなるのをブロックをブロックです。いの?となっており外部のブロック...

C++での範囲、自動変数で制限を巻きブレースを取り巻くします。かもこのようにすることを目的に作成されてplunkingを下ってみキーワードの外に巻きブレース?

のようにravenspoint指摘の通り、皆様の期待変数のブロック定義されます。 try を紹介するブロックとな catch.

したい場合は変数の地域の両方 trycatch, み封入るにもかかわらず、そのブロック:

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

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

シンプルに答えると、Cのほとんどの言語継承したその構文はブロックscoped.その場合変数が定義されたブロック、すなわち、{}でした。

のように、JavaScriptでは、同様の書式で機能scoped.JavaScriptで宣言した変数がtryブロック範囲のcatchブロックは、随所に他に含ます。

@勢を貫いての問題を理由としては、回答が正しくものとして注したかったの追加をおすすめ液の例では良い99.9999+%の時間になる学生の学習機会の質の管理の方がはるかに安全なのかチェックのためにnullを使用する前に何かインスタンスを生成のtryブロック、または変数を初期化するものではなく宣言では、tryブロックです。例えば:

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);
   }
}

いということは確かで伸縮自在なスケーラビリティの回避策でも何をやっているのをtryブロックはより複雑する時に、対応することができるでしょうが安全にアクセスのデータからcatchブロックです。

その答えに、皆様の指摘のように、かなりの方のブロック定義".

あなたが、コードなどの見.見 アーム

 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
}

更新: アームはJava7. http://download.java.net/jdk7/docs/technotes/guides/language/try-with-resources.html

それによる"というスローキャッチ例外"のレッスンにはレッスン2 MCTS自身のペースで研修キット(受験70-536):Microsoft®です。NET Framework2.0—アプリ開発財団, の理由は、この例外が発生前の変数の宣言は、tryブロック(その他を行っている既).

見積もりから25ページ:

お知らせ"のStreamReader宣言に移転外のTryブロック前の一例です。これは、最後にブロックアクセスできない変数で宣言された内は、Tryブロックです。 このう意味があるので、場所により例外が発生した変数の宣言のみのブロックがまだ実行されているのは."

だ液であるようだ。できないことを宣言したものをtryブロックのような別の例外をキャッチブロックです。

かけなければならないのは仕事として別のスコープ.

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

これらの変数はブロックレベルに限定していくブロックです。同様に定義される変数です。いたします。

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

の文字列になりません宣言されていないのですっ。

では、tryブロックのcatchブロックは2つの異なるブロックとなります。

以下のコードいただけますでしょうが期待s定義されたブロックできるブロック。

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

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

の特定の例ださinitialising sできない例外をスローします。まだ考えるか、その範囲が延長することができます。

が一般的に、initialiser表現がスローされる可能性があります。るのではなく、意味の変数がinitialiser投げた例外(または宣言した後、別の変動が起こった)する範囲のためのcatch/ついに登場。●

また、コードの可読性が損をする。の規定はC言語では、このような、C++、Java、C#)ソフトバンクグループ変数のスコープのフォロブロックとなります。

したい場合は変動する範囲をtry/catch/うがなか他の、あなたのプを通しのものもセットのブレース(ベアブロック)することを宣言変数の前に挑戦しました。

の理由って支えられているため、同じ範囲で任意の点のみのブロックできるスローされる例外です。れば、同一の範囲、さらに被で置によっては例外がスローされるまで、もっと曖昧なものです。

少なくともその宣言された外部のみのブロックでは、ご存知のためにはどのように変数の最小できる場合、例外がスローされます;変数の値を前にしてみます。

きを宣言するローカル変数でのスタック(一部の種類の値をオブジェクトのスタック、その他の種類の参照だけのスタック).がある場合、例外と内をtryブロック、ローカル変数内でのブロックが解放され、スタックは"繰り出し"の状態にした時の初めには、tryブロックです。これによりデザイン。ではtry/catchできるしなければならないすべての関数呼び出し、ブロックをシステムに戻す機能。この機構を使用しなけできない状態のものが例外が発生します。

をエラー処理コードな外部で宣言した変数を値に変更内のtryブロックのように悪いデザインです。うのは基本的に漏れた資源を意図的に得るためには、情報(この特定の場合でいいのだけを情報の漏洩が想像した場合とその他の資源か?まだない生命のくにをお楽しみください。私はあなたを崩してみブロック小さなチャンクに必要な場合は、より粒度エラーになります。

きていくべきでは知ることの誤りでも取り上げられるもので捨てる.Theese例外クラス正常に伝えて必要なすべての例外です。ない場合することができるようになりま独自の例外クラスおよびパス情報です。そのように、または変数の中からtryブロックでは、例外は自己explainatory.だいくんだデザインを考えてみましょうものがある場合、その他、できるか予測する例外を再利用でき、情報を再開から、例外、およびそrethrow独自の例外です。

として指摘されている他のユーザーを巻きブレースの定義の範囲でほとんどのCスタイルの言語を知っています。

の場合は単純変数、なぜ介されている範囲?ではその大人のみ対象となります。

クライアントまで、フルのC#であれば複雑に変動することになりますの実施IDisposable.できる次のいずれかの条件が成立する利用をtry/catch/最後に呼び出obj.Dispose()の最後にブロックです。または利用できるのをキーワードに、自動的に呼び処分期末のコードです。

Pythonうに見えるのがcatch/最終的に、ブロックの場合には、宣言していなかった投.

どの場合、例外がスローされますの一部のコードは上記の宣言を可変となります。この宣言自体は満足です。

try {

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

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

なお例で変なことはありません、この同一:

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

この原因となるチリをキャッチを投げるように、null参照例外の場合コード1。現在の持つ意味をtry/catchも十分に認識されており、このように感コーナーの場合には、sを定義の初期値を入力してください理論的にはnullにできませんが、共通の意味でとなってしまいます。

再びこの理論によって固定されるのみを分離定義です(String s; s = "1|2";)、またはその他の設定の条件では一般的に簡単に言えばいいます。

いただくことは、意味の範囲を定義する世界に例外なく、具体的には、地元の人々だけど、 {} で定義され、すべての例です。軽微な点がポイントです。

最後に、私たいものを追加することができます設定のカッコにうすることができました。の範囲いがなく、コストの少し読みやすさがない。

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

私たちの思考することでも、tryブロックを引き起こした例外の名前空間内容の信頼を得られないから-ieを参照の文字列's'をキャッチブロック発生の原因になりませんが、他の例外です。

もっていることを確認してください捨てコンパイルエラーとして始めたから新築したこう宣言しますので、その方法がありうるのみを宣言するのでみてみます。で強制するには、明示的な境内にある変数が存在するという前提になっていました。

した場合は無視するコーピング-ブロック課題の一瞬のcomplierいて多く状況なども定義されています。こでは不可能であり、スコーピングエラーにも力を、いま、著者のコードを実現含意のコードを書きます(この文字列sからnullの可能性があるのがcatchブロック).がコードした法律の場合には、OutOfMemoryの例外からも保証割り当てられるメモリスロット:

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

のCLR(およびそのためコンパイラ)も力する変数の初期化する前に使用します。をキャッチブロックを提示できないことを保証す.

このコンパイラーをたくさんの作品は、実際に学んでいくスタイルではありませんの利益とでしょう混同する人々がいいってみてはいかがでしょうか/catch作品とは異なります。

のほか、濃度による許可しない"パッケージ、付着するので設置スコーピングマの使い方の言語、コンパイラとCLRに提供できるよ保証の状態変数の中にcatchブロックです。に存在するとして初期化されます。

この言語でデザイナーブとその他を構築しまう を使用ロック の問題と範囲が定義することができますwriteより明確にコードです。

例えばの を使用 キーワード IDisposable オ:

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

に相当す:

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

場合はtry/catch/よく理解し、リファクタリングの導入など他の層の間接指定中間のクラスがカプセル化の意味は何しようとしている国での生活を経験しました。を見ることなくリアルコードできます。

の代わりにローカル変数は、公共財が起動させることができる;これも避けることも潜在的エラーの割り当てられない可変となります。公文字列S{get;セット}

C#仕様 (15.2)国"の範囲の変数や定数を宣言されたブロックistのブロックです。"

(初めての例では、tryブロックをブロック"s"が宣言された)

る場合の操作に失敗したネイチャーツアーをセッ決してnull以外の参照、割り当てられない可変となります。

C#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;
})();
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top