web-dev-qa-db-ja.com

C#で、tryブロック内で宣言された変数のスコープが制限されているのはなぜですか?

エラー処理を追加したい:

var firstVariable = 1;
var secondVariable = firstVariable;

以下はコンパイルされません:

try
{
   var firstVariable = 1;
}
catch {}

try
{
   var secondVariable = firstVariable;
}
catch {}

他のコードブロックのように、try catchブロックが変数のスコープに影響を与える必要があるのはなぜですか?一貫性のために、リファクタリングの必要なしにエラー処理でコードをラップできるのは意味がないのではないでしょうか。

24
JᴀʏMᴇᴇ

コードが次の場合:

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

try
{
   var secondVariable = firstVariable;
}
catch {}

ここで、メソッド呼び出しがスローする場合、宣言されていない変数(firstVariable)を使用しようとしています。

:上記の例は、特に「一貫性を確保する」という元の質問に答えています。これは、一貫性以外にも理由があることを示しています。しかし、ピーターの答えが示すように、また一貫性からの強力な議論があり、それは確かに決定において非常に重要な要素だったでしょう。

91
Ben Aaronson

これはBenによって十分に回答されていることは知っていますが、便利に取り除かれた一貫性のあるPOVに対処したいと思いました。 try/catchブロックがスコープに影響を与えなかったとすると、次のようになります。

{
    // new scope here
}

try
{
   // Not new scope
}

そして、私にとってこれは Principle of least astonishment(POLA) にぶつかります。なぜなら、あなたは{}がその前にある状況に応じて二重の義務を果たしているからです。

この混乱から抜け出す唯一の方法は、try/catchブロックを描くために他のマーカーを指定することです。コードのにおいを追加し始めます。そのため、言語にtry/catchのスコープがなくなるまでには、スコープバージョンの方が適していたような混乱があったでしょう。

64
Peter M