プロが教えるわが家の防犯対策術!

Net 2.0のC#で同一名の変数を使う場合について質問いたします。

以下のHoge1の場合には「 ローカルの変数 'x' をこのスコープで宣言することはできません。これは、'親またはカレント' スコープで別の意味を持つ 'x' の意味が変更されるのを避けるためです。」と怒られます。

一方、Hoge2の場合には怒られません。

Hoge2内でx=1;ではなくint x=1;と再宣言しているにもかかわらず怒られないのは、Hoge1が厳格にスコープ管理している点からみると意外に感じられます。

http://www.atmarkit.co.jp/ait/articles/0210/16/n … の記述を見ると、この記事が書かれた2002年ごろにはHoge2もNGだったような印象を受けるのですが、変化があったのでしょうか?

この辺りの事情に詳しい方がおられましたらよろしく、お願い申し上げます。

class Class1
{
   private void Hoge1()
   {
      int x;
      {
         int x = 2; // これはNG!。「ローカルの変数 'x' をこのスコープで宣言することはできません。これは、'親またはカレント' スコープで別の意味を持つ 'x' の意味が変更されるのを避けるためです。」と怒られる。
      }
   }

   int x;
   private static void Hoge2()
   {
      int x=1; //これはOK!親にぶらさげた変数が通る。
   }
}

A 回答 (2件)

>変化があったのでしょうか?



質問文で掲示されているページの記事と、質問者さんの例(ほげ1ほげ2)は、表記は違えど「同じ事を言っている」ように見えるんですが。

「何も変わってない」と思いますが、どうでしょう?
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。


//http://www.atmarkit.co.jp/ait/articles/0210/16/n … からのコピペ改変(xをyに変更)
private static int y = 0;
static void sample1()
{
    int y = 2; // ローカルの変数 'x' をこのスコープで宣言することはできません。これは、'親またはカレント' スコープで別の意味を持つ 'x' の意味が変更されるのを避けるためです。
}
上記を、VisualStudio2012でコピペで動かしてもやはりエラーが発生しないのであります......


------------------------------------------------------------------
その後、自分でも検討した結果、以下のことが分かったので後学のために記述します。

public class Class1
{
    private void Hoge1()
    {
        int x;
        {
            int x = 2; // これはNG!。「ローカルの変数 'x' をこのスコープで宣言することはできません。これは、'親またはカレント' スコープで別の意味を持つ 'x' の意味が変更されるのを避けるためです。」といわれる。
        }
    }

    int x;
    private void Hoge2()
    {
        int x = 1; //このぶらさげ変数はOK!
    }

(1)Hoge2の{ }内のint x = 1;のxは{ }内のみにスコープを持つローカル変数として宣言されており、親のint x;とは無関係でスコープは及んでいない。→これは理解できる仕様である。
(2)ところが、Hoge2の{ }内のint x = 1;実行直後、親のint xにマウスをホーバーさせて内容をクイックウォッチすると1がはいってる(ように見えるため)、スコープが親のint xに通ってる(ように見える)!!→「え’’~、おかっしいなぁ」と感じる。
(3)これは、クイックウォッチが変数名のみで判断して中身表示してるためのようで、イミディエイトウインドウでClass1.xをみるとnullのままである。したがって、Hoge2の{ }内のローカル変数xのスコープは、親のxに及んでいないことがわかる。
------------------------------------------------------------------

上記より、
a)クイックウォッチの仕様にやや問題があるのでは?
b)昔の文法のほうが厳格で、親にぶら下げたglobal的変数名をローカルで宣言してまったときに気づきやすい。よって、今の文法でも「ローカルの変数 'x' をこのスコープで宣言することはできるが、'親またはカレント' スコープでも同一名で宣言されてるが、わかってるんだろうな!」くらいの警告がほしい。

お礼日時:2014/03/02 11:09

詳しいって訳ではありませんが……。


# ということで、正しい内容についてはもっと詳しい方の回答待ちになりますかな。

>int x = 2; // これはNG!。

エラーで書かれているように、Hoge1()直下でのローカル変数なのか、その下に作ったローカルなブロック内での変数なのか判別する手段がない(あるいは煩雑過ぎる)ので駄目なのでしょう。

>int x=1; //これはOK!親にぶらさげた変数が通る。

静的メソッドから、非静的クラスフィールド(int x;)へのアクセスはできませんから判別できない。という状況にはならないのでしょう。

参考URL:http://ufcpp.net/study/csharp/oo_static.html
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

    int x;
    private void Hoge2()
    {
        int x = 1; //このぶらさげ変数はOK!
    }
とstaticをはずしても、相変わらず//ぶらさげ変数はOK!となる模様であります。。

お礼日時:2014/03/02 10:33

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!