趣味で始めるプログラミング

プログラミングを個人の趣味として楽しむブログ

今更ながらのローカル変数

今ならながら、ローカル変数に関して仕様を確認する。

 

こういう仕様は、実は言語ごとに微妙に違っていたりして確認すると楽しいことが時々あるので好きなんだけど、今回意外だったのは次の2点。

 

  • C#は基本的に静的な型付き言語で例外はobject型とdynamicの2つ
  • コンパイラが変数名の重複のチェックを行う範囲はスコープではなく宣言空間

 

まず1点目。C#が静的な型付き言語である点に関しては、普通に変数の宣言時に型も一緒に定義しているので特にこれといって驚くことではなかったのですが、実は例外にvarが入っていなかったことに引っ掛かりを覚えました。確か変数の型をvarで定義すると、実際にはどの型として扱ってもよかったような気がしたのですが…

これに関してちょっと調べてみると、実はvarは最初に使われる時の変数の型にコンパイラが自動的に置き換えているだけで静的な型付きの範囲から花ずれてはいないようでした。

 

 次が宣言空間に関してで、これは具体的には、下記の様なコードはエラーになるというもの。ネストの宣言空間内では親の宣言空間内の変数と名前が重複してはいけないのだそうな…


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Boolean flg = true;
            int i = 0;

            if (flg)
            {
                int i = 1;	//コンパイルエラー
            }
        }
    }
}

 あと、宣言空間に関してはもう一つルールがあり、ブロックのどこで定義しても振る舞いは変わらないとなっています。つまり、こんなのもNGです。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Boolean flg = true;

            if(flg)
            {
                int i = 1;
            }

            int i = 0;	//コンパイルエラー
        }
    }
}

 

 この二つを知らないでコンパイルエラー*1出されると、結構苦しいかも?

 

*1:CS0136 ローカルまたはパラメーター 'i' は、その名前が外側のローカルのスコープでローカルやパラメーターの定義に使用されているため、このスコープでは宣言できません。 Program.cs 18 アクティブ