代码改变世界

C#学习笔记(1)——变量的声明与赋值

2007-09-03 20:54  Nicholas Yuen  阅读(1557)  评论(2编辑  收藏  举报

要点:变量的赋值只能在方法或构造函数中进行。譬如类构造函数,类型构造函数(也叫静态构造函数),类方法中进行赋值。
如果尝试在定义类成员的时候用赋值符号"="对变量(不管静态的还是非静态的)进行赋值操作的话,则编译不能。如下面的代码:

 1 using System;
 2 
 3 namespace Test
 4 {
 5     class Program
 6     {
 7         int i;
 8         i = 10// Invalid token '=' in class, struct, or interface member declaration
 9         static void Main(string[] args)
10         {
11             // 
12         }
13     }
14 }

可以在声明的时候给变量初始化变量的值,如下面代码。

 1 using System;
 2 
 3 namespace Test
 4 {
 5     class Program
 6     {
 7         int i = 10;
 8         static void Main(string[] args)
 9         {
10             // 
11         }
12     }
13 }
14 

实际上,对实例变量i的赋值是交给类Program的默认构造函数(.ctor())进行的。如 Program p = new Program(); 在实例化类Program时就已经把i的值赋值为10了。
我们来看一下上面程序的IL代码


.ctor : void()  的IL代码:

.method public hidebysig specialname rtspecialname 
        instance 
void  .ctor() cil managed
{
  
// Code size       16 (0x10)
  .maxstack  8
  IL_0000:  ldarg.
0
  IL_0001:  ldc.i4.s   
10
  IL_0003:  stfld      int32 Test.Program::i
  IL_0008:  ldarg.
0
  IL_0009:  call       instance 
void [mscorlib]System.Object::.ctor()
  IL_000e:  nop
  IL_000f:  ret
// end of method Program::.ctor

假如为静态成员变量,则变量的赋值工作交给类型构造函数(静态构造函数)进行。

 1 using System;
 2 
 3 namespace Test
 4 {
 5     class Program
 6     {
 7         static int i = 10;
 8         static void Main(string[] args)
 9         {
10             // 
11         }
12     }
13 }
14 

IL代码:

注意这里多出了一个.cctor : void() 方法来了。实际上它是类型构造函数(class constructor)
我们来看看 .cctor : void() 和 .ctor : void() 的IL代码。

.cctor : void()

.method private hidebysig specialname rtspecialname static 
        
void  .cctor() cil managed
{
  
// Code size       8 (0x8)
  .maxstack  8
  IL_0000:  ldc.i4.s   
10
  IL_0002:  stsfld     int32 Test.Program::i
  IL_0007:  ret
// end of method Program::.cctor

.ctor : void()

.method public hidebysig specialname rtspecialname 
        instance 
void  .ctor() cil managed
{
  
// Code size       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.
0
  IL_0001:  call       instance 
void [mscorlib]System.Object::.ctor()
  IL_0006:  ret
// end of method Program::.ctor

上面的情况是在声明一个变量的时候同时给它赋值(也叫初始化吧)。
下面我们来看看只是声明一个变量,然后在类的方法里面给它赋值的情况。

情况一:声明类成员变量(非静态)

 1 using System;
 2 
 3 namespace Test
 4 {
 5     class Program
 6     {
 7         int i;
 8         public void Method()
 9         {
10             i = 10;
11         }
12         static void Main(string[] args)
13         {
14             // 
15         }
16     }
17 }

IL代码:


.ctor : void()

.method public hidebysig specialname rtspecialname 
        instance 
void  .ctor() cil managed
{
  
// Code size       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.
0
  IL_0001:  call       instance 
void [mscorlib]System.Object::.ctor()
  IL_0006:  ret
// end of method Program::.ctor

.Method : void()

.method public hidebysig instance void  Method() cil managed
{
  
// Code size       10 (0xa)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldarg.
0
  IL_0002:  ldc.i4.s   
10
  IL_0004:  stfld      int32 Test.Program::i
  IL_0009:  ret
// end of method Program::Method



情况二:声明类静态成员变量。

 1 using System;
 2 
 3 namespace Test
 4 {
 5     class Program
 6     {
 7         static int i;
 8         static void Main(string[] args)
 9         {
10             i = 10;
11         }
12     }
13 }

IL:代码

.ctor : void()

.method public hidebysig specialname rtspecialname 
        instance 
void  .ctor() cil managed
{
  
// Code size       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.
0
  IL_0001:  call       instance 
void [mscorlib]System.Object::.ctor()
  IL_0006:  ret
// end of method Program::.ctor

Main : void(string[])

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  
// Code size       9 (0x9)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldc.i4.s   
10
  IL_0003:  stsfld     int32 Test.Program::i
  IL_0008:  ret
// end of method Program::Main

看到了吧。变量全都是在方法或构造函数里面进行赋值的(上面的都是简单值类型的变量的测试,其他类型的有时间再研究研究)。
(对不起各位看官了,贴了一大堆IL代码)