6

次のコードがコンパイルされるのはなぜですか? foo2番目のケースブランチで宣言されていないことについて不平を言うと思います。コンパイラは、すべてのケースのスコープ内にあるように宣言を処理しますか?

using System;

namespace Scratch
{
    class Scratch
    {
        public static void Main()
        {
            var x = 2;
            switch (x)
            {
                case 1:
                    var foo = "one";
                    Console.Out.WriteLine(foo);
                    break;
                case 2:
                    foo = "two"; // is foo in scope here?
                    Console.Out.WriteLine(foo);
                    break;
            }
        }
    }
}
4

4 に答える 4

9

次のコードがコンパイルされるのはなぜですか?

言語はこの特定の領域で脳死の方法で設計されているため:(

ローカル変数のスコープは、それが宣言されているブロックであり、宣言後の任意の時点でレキシカルにアクセスできます。

いいえ、私もそのように言語を設計しません。私は C# での switch の設計のファンではありません...

于 2012-09-13T23:36:56.487 に答える
8

@JonSkeet が言ったことは正しいです。C/C++/C# の意味での「ブロック」は、論理的な意味での「ケース」と同じではありません。しかし、彼は問題を解決するための「ベスト プラクティス」については触れていません。switch ステートメントの 1 つのケース内で変数を宣言する場合は、論理的な「ケース」全体をブロックでラップすることをお勧めします。このようにして、コンパイラによって認識される論理的な「ケース」と実際の「スコープ」はまったく同じになります。

public static void Main()
{
    var x = 2;
    switch (x)
    {
        case 1: {  // notice these braces I added
            var foo = "one";
            Console.Out.WriteLine(foo);
            break;
        }
        case 2:
            foo = "two"; // hooray! foo is no longer in scope here
            Console.Out.WriteLine(foo);
            break;
    }
}
于 2012-09-13T23:43:43.447 に答える
3

コンパイルしないようにするには、次のように中括弧を使用してスコープを設定できます。

using System;

namespace Scratch
{
    class Scratch
    {
        public static void Main()
    {
        var x = 2;
        switch (x)
        {
            case 1:
            {
                var foo = "one";
                Console.Out.WriteLine(foo);
                break;
            }
            case 2:
            {
                foo = "two"; // is foo in scope here?
                Console.Out.WriteLine(foo);
                break;
            }
        }
    }
}

これにより、var foo がその特定のスコープ内にのみ存在するようになります。

于 2012-09-13T23:42:05.763 に答える
1

C# では、変数はブロック レベルでスコープされます。ブロックが switch ステートメントの後に続くため、どちらの場合も foo は実際にスコープ内にあります。

于 2012-09-13T23:39:56.913 に答える