有关C# 变量作用域问题

lwj057 2008-12-31 01:16:57
我今天突然发现了一个在C#中奇怪的现象,百思不得其解,请各位高手指点下,详细点,兄弟是初学者,谢了。
问题:

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int i;
string test;//第一行
for (i = 0; i < 10; i++)
{
test = "line";
Console.WriteLine(test);
}
Console.WriteLine(test );
Console.ReadKey();
}
}
}

调试不成功 错误提示是 “ 使用了未赋值的局部变量“test” ”
如果说是还没给第一行的test 赋值的话
但为什么这样后又可以了:

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//int i;
string test;//第一行
// for (i = 0; i < 10; i++)
{
test = "line";
Console.WriteLine(test);
}
Console.WriteLine(test );
Console.ReadKey();
}
}
}
也没赋值却可以成功

请各位说下这里面的原因 谢了
...全文
290 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
ILOVEYOUMYWIFERE 2009-01-14
  • 打赏
  • 举报
回复
看了
denglei12 2009-01-14
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 sharydu 的回复:]
跟声明的位置有关。
全局变量(类内)在声明时可以不赋初值。而局部变量(方法内)必须在声明的同时赋初值。
[/Quote]

同意。
rufidmx 2009-01-14
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 gomoku 的回复:]
引用 13 楼 gomoku 的回复:
...编译器不认可在循环,条件分支等中的赋初值代码...


这句话容易造成误解。编译器还是很聪明的,当所有条件分支都能给变量赋初值,
该种初始化将被认可,比如下面的代码。
但是,如果条件分支不能涵盖所有情况,初始化同样不被认可,比如反注释下面代码第6行后的情况。

C# code
string str;
if (Environment.TickCount % 2 == 1)
{
str = "hello";
}
else //if (Environme…
[/Quote]
高。完全正解。我试验过了。学习。。。
yuanhuiqioa 2009-01-13
  • 打赏
  • 举报
回复
学习
hechenqingtian 2009-01-02
  • 打赏
  • 举报
回复
static void Main(string[] args)
{
int i;
string test;//第一行
for (i = 0; i < 10; i++)
{
test = "line";
Console.WriteLine(test);
}
Console.WriteLine(test);
Console.ReadKey();
}

注意如果使用局部变量则必须赋初始值,如果使用全局变量 则不需赋初始值
private int i;
private string str;
static void Main(string[] args)
{
int i;
string test;//第一行
Program p = new Program();
Console.WriteLine(p.i + " " + p.str);
}



贴主的第二种情况
static void Main(string[] args)
{
//int i;
string test;//第一行
// for (i = 0; i < 10; i++)
{
test = "line";
Console.WriteLine(test);
}
Console.WriteLine(test );
Console.ReadKey();
}
注视了循环test 就复制了
sharydu 2009-01-01
  • 打赏
  • 举报
回复
跟声明的位置有关。
全局变量(类内)在声明时可以不赋初值。而局部变量(方法内)必须在声明的同时赋初值。
gomoku 2008-12-31
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 gomoku 的回复:]
...编译器不认可在循环,条件分支等中的赋初值代码...
[/Quote]

这句话容易造成误解。编译器还是很聪明的,当所有条件分支都能给变量赋初值,
该种初始化将被认可,比如下面的代码。
但是,如果条件分支不能涵盖所有情况,初始化同样不被认可,比如反注释下面代码第6行后的情况。

string str;
if (Environment.TickCount % 2 == 1)
{
str = "hello";
}
else //if (Environment.TickCount %2 == 0 )
{
str = "world";
}
MessageBox.Show( str );

gomoku 2008-12-31
  • 打赏
  • 举报
回复
目前编译器不会自动把你的循环展开,
不能确保循环里的代码一定会运行到。


void MyMethod(int c)
{
for(int i=0; i<c; i++)
{
// 谁能确定这行一定运行的到? 如果c=0呢?
}
}


因此,编译器不认可在循环,条件分支等中的赋初值代码,
并产生“用了未赋值的局部变量”的编译错误。

wangfeizjk 2008-12-31
  • 打赏
  • 举报
回复
大家都给讲明白了,我就飘过了。。。。。。。
bhtfg538 2008-12-31
  • 打赏
  • 举报
回复
如果没有初始值
CLR 编译的时候 会为你的 string test =null;
后面继续赋值的话还是要成功的,不过 会警告...使用了为赋值的test
king19840811 2008-12-31
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 hbxtlhx 的回复:]
这个只是个警告,没有关系的。
[/Quote]
赞成这个。。现在是找问题,不是说编程习惯的问题。实现不行你看下ildasm中的情况就知道了
qingdaowxz 2008-12-31
  • 打赏
  • 举报
回复
大家都说了。。
ztlyz84 2008-12-31
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 javakiki 的回复:]
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int i;
          string test="";//第一行
            for (i = 0; i < 10; i++)
            {
                test = "line";
                Console.WriteLine(test);
            }
            Console.WriteLine(test );
            Console.ReadKey();
        }
    }

[/Quote]

4楼, 正解!
猿敲月下码 2008-12-31
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 hbxtlhx 的回复:]
这个只是个警告,没有关系的。
[/Quote]
Use of unassigned local variable 'test' 编译不能通过,怎么会没有关系呢?
jefflovejava 2008-12-31
  • 打赏
  • 举报
回复
下面的那个等于给test赋了初值“line”

而上面的那个没有赋初值,就直接进行下面的逻辑了,编译器会提示你那个警告,

为了保持良好编程习惯,你就设置个初值吧,null,string.empty都行
Dobzhansky 2008-12-31
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 Dobzhansky 的回复:]
因为 test 声明, 和赋值靠着
[/Quote]

我的错了
设备管理系统 2008-12-31
  • 打赏
  • 举报
回复
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int i;
string test="";//第一行
for (i = 0; i < 10; i++)
{
test = "line";
Console.WriteLine(test);
}
Console.WriteLine(test );
Console.ReadKey();
}
}
}

千万记住,C#变量要赋初值
止戈而立 2008-12-31
  • 打赏
  • 举报
回复
在声明时写成 string test=string.Empty;

虽然你在for语句内赋了值,但在编译时,程序是不会for语句内的代码能否执行到的.
因此会认为你没有赋值就使用了.
Dobzhansky 2008-12-31
  • 打赏
  • 举报
回复
因为 test 声明, 和赋值靠着
北京的雾霾天 2008-12-31
  • 打赏
  • 举报
回复
这个只是个警告,没有关系的。

111,131

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧