[解決済み] try "で宣言された変数が "catch "や "finally "のスコープに入らないのはなぜですか?
質問
C#やJavaでは(おそらく他の言語でも)、"try"ブロック内で宣言された変数は、対応する"catch"や"final"ブロックでは範囲外になっています。 例えば、次のようなコードはコンパイルできません。
try {
String s = "test";
// (more code...)
}
catch {
Console.Out.WriteLine(s); //Java fans: think "System.out.println" here instead
}
このコードでは、catchブロックのsへの参照でコンパイルエラーが発生します。sはtryブロックの中でのみスコープに存在するからです。 (Javaの場合、コンパイルエラーは "s cannot be resolved" C#の場合は "The name 's' does not exist in the current context" となります)。
この問題の一般的な解決策は、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-finally のコンテキストのみではなく、メソッドの残りの部分すべて)。
この言語設計の決定には、どのような根拠があったのでしょうか(Java、C#、その他該当する言語において)。
どのように解決するのですか?
2つあります。
-
一般に、Javaのスコープは、グローバルと関数の2段階だけです。 しかし、try/catchは例外です(ダジャレではありません)。 例外が発生し、例外オブジェクトに変数が代入されると、そのオブジェクト変数は "catch" セクション内でのみ利用可能で、catch が完了すると同時に破棄されます。
-
(そしてもっと重要なこと)。tryブロックのどこで例外が発生したのか、知ることができないのです。あなたの変数が宣言される前かもしれません。したがって、どの変数がcatch/finally句で利用できるようになるかは、わからないのです。次のような場合、スコープがあなたの提案通りであることを考えましょう。
try { throw new ArgumentException("some operation that throws an exception"); string s = "blah"; } catch (e as ArgumentException) { Console.Out.WriteLine(s); }
これは明らかに問題です。例外ハンドラに到達したとき、sは宣言されていないことになります。catchは例外的な状況を処理するためのものであり、finallysは例外的な状況を処理するためのものであることを考えると、これは明らかに問題です。 は 実行する前に、コンパイル時に安全性を確認し、問題を宣言しておくことは、実行時よりもはるかに良いことです。
関連
-
[解決済み] メンバー '<メンバー名>' にインスタンス参照でアクセスできない
-
[解決済み】C#はJavaのcharAt()と同等?)
-
[解決済み】C# - パスに不正な文字がある場合
-
[解決済み] EntityTypeにキーが定義されていないエラー
-
[解決済み] JavaScriptの変数のスコープとは何ですか?
-
[解決済み] Try-catchは私のコードをスピードアップさせるか?
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] なぜすべてのブロックを "try"-"catch "で包んではいけないのですか?
-
[解決済み】再試行キャッチはどのように実装するのですか?
-
[解決済み】try {...} finally {...} は良くて、try {...} catch{} はダメなのはなぜ?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】"出力タイプがクラスライブラリのプロジェクトは直接起動できない"
-
[解決済み】C#におけるtypedefの等価性
-
[解決済み】SmtpException: トランスポート接続からデータを読み取れません:net_io_connectionclosed
-
[解決済み】クロススレッド操作が有効でない。作成されたスレッド以外のスレッドからアクセスされたコントロール
-
[解決済み】Socket.Selectがエラー "An operation was attempted on something that is not a socket" を返す。
-
[解決済み】aspNetCore 2.2.0 - AspNetCoreModuleV2 エラー
-
[解決済み】IntPtrとは一体何なのか?
-
[解決済み] 関数を終了するには?
-
[解決済み】Microsoft.Extensions.LoggingからILoggerを解決することができない
-
VSでscanfエラーを恒久的に解決するには、ソースファイルを作成し、自動的に#define _CRT_SECURE_NO_WARNINGS 1を追加してください。