C# 变量作用域


变量的作用域是可以访问该变量的代码区域
作用域遵循规则
成员变量
类在某个作用域中,其字段也在该作用域内
局部变量
存在于声明该变量的块语句或方法结束的右花括号{}之前的作用域内
for、while或类似语句中声明的局部变量存在于该循环体内
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HelloWord
{
    class Program
    {
        String str1 = "object variable";//实例变量
        static String str2 = "static variable";//静态变量
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            Console.WriteLine(str2);
            //Console.WriteLine(.str1); // 对象引用对于非静态的字段、方法或属性“Program.str1”是必需的    

            Program p = new Program();
            Console.WriteLine(p.str1);

            for(int i = 0; i < 3; i++)
            {
                Console.WriteLine(i);
            }
           // Console.WriteLine(i);//错误 CS0103  当前上下文中不存在名称“i”     i作用域在 for 循环中
            Console.ReadKey();
        }
    }
}
局部变量的作用域冲突
大型程序在不同部分的变量使用相同的变量名很常见。
只要变量的作用域是程序的不同部分,就不会有问题 不会产生多义性。
同名的局部变量不能在统一作用域声明两次
public static int Main(){
int j=20;
for(int i=0;i<10;i++){
  int j=30;
  Console.WriteLine(j+i);
  }
}
编译时提示的错误 First.cs(24,10): error CS0136:
不能在此范围内声明名为“j”的局部变量,因为这样会使“j”具有不同的含义,而它已在“父级或当前”范围中表示其他内容了。

根据变量的作用域遵循的原则
局部变量存在于声明该变量的块语句或方法结束的右花括号({})之前的作用域内)
第一个变量j是在for循环开始前定义的,它的作用域是Main()方法;
第二个变量的作用域是在for循环;
第一个变量j的作用域包含了第二个j的作用域。
对编译器来说会存在歧义,因为编译器无法区分这两个变量,所以不允许声明第2个 变量
2.字段和局部变量的作用域冲突
某些情况下,可以区分名称相同、作用域相同的两个标志符。
此时编译器允许声明第2个变量。
原因是C#在变量之间有一个基本的区分,他把类级别声明的变量看作字段(成员变量),
而把方法中声明的变量看作局部变量
using System;
namespace Wrox
{
  class ScopeTest{
  public int j=20;
  public static void Main(){
        int j=30;
        Console.WriteLine(j);
        return;
        }
    }
}
虽然在Main()方法中作用域中声明了两个变量,这段代码会正常编译。
第一个j的作用域是这个ScropeTest类,第一个为Main()方法。
此时,在Main()方法中声明的变量隐藏了同名的类级变量,所以这段代码,会显示数字为30

引用类级变量,可用语法object.fieldname
using System;
namespace Wrox
{
  class ScopeTest{
  public int j=20;
  public static void Main(){
        int j=30;
        Console.WriteLine("局部变量是:"+j);
        ScopeTest obj=new ScopeTest();
        Console.WriteLine("类级变量是:"+obj.j);
        return;
        }
    }
}
局部变量是:30
类级变量是:20
可以选择将字段声明为 static
调用方在任何时候都能使用字段,即使类没有任何实例
namespace Wrox
{
  class    ScopeTest{
  static int j=20;
  public static void Main(){
        int j=30;
        Console.WriteLine(j);
        // ScopeTest obj=new ScopeTest();
        Console.WriteLine("类级变量是:"+ScopeTest.j);
        return;
        }
    }
}