声明之前使用但在使用后声明的变量

时间:2017-05-03 15:48:24

标签: c#

我有一段代码,其中包含标题中所述的方面。

public string ReplaceCC(Match m)// Replace each Regex cc match with the number of the occurrence.
{ 
    i++;//it's used in function before declaration
    return i.ToString() + i.ToString();     
} 

public static int i=0;
}

我认为在我的脑海中存在编辑/声明的混乱。这里的问题是什么?

4 个答案:

答案 0 :(得分:0)

您声明变量超出函数范围,作为静态类变量:

public static int i=0;

在创建静态实例时,第一次尝试使用变量时会初始化变量。

答案 1 :(得分:0)

您在范围之外声明变量,它是一个全局变量。

例如:

public class Person
{
    public Person(string name)
    {
        this.Name = name;
    }

    public string Name { get; set; }
}

此代码在Person的根目录中声明变量Name。

答案 2 :(得分:0)

尽管我能够感知到,令你感到困惑的是它被声明的代码顺序。看看下面的代码:

class Program
{
    public Program()
    {
    }

    public  void myFunc()
    {
        canIAccessIt = 10;
    }

    public  int canIAccessIt = 0;
}

与上面的代码一样,来自C语言背景的任何人(忽略C中不存在的类部分)可能会认为myFunc函数试图访问变量canIAccessIt甚至在宣布或进入范围之前。

C#.Net世界中变量的范围并不是那样的。类级变量(也称为成员变量)与对象的实例相关联,并且从创建对象到对象被销毁或垃圾​​回收的时间进入范围。

与上述情况一样,人们可能认为canIAccessIt变量可能不会生效,因为它在myFunc方法下面声明。它所以。

当我的上面的代码是由C#编译器编译的时候,在你的* .dll文件中编写的MSIL(Microsoft中间语言)就是这样的,这是C#项目构建过程的输出:

class Program
{
    public  int canIAccessIt;
    public Program()
    {
        canIAccessIt = 0;
    }

    public  void myFunc()
    {
        canIAccessIt = 10;
    }
}

注意:上述MSIL代码仅供参考,以便您了解它。 MSIL代码看起来比这更奇怪,因为它必须由CLR而不是用户或程序员理解。

因此,对于编译器而言,在类中声明全局变量的位置并不重要。只要它在您的类的开头({)和结束大括号(})内,那么它的初始化将在您的类的构造函数内移动。类的构造函数是第一个在新建类实例时调用的方法。在它发生的那一刻,你的变量将变为生命(经过实例化和初始化),并成为范围,供myFunc方法使用。

类中i变量的唯一区别是它是静态的,因此它的初始化将移动类的静态构造函数而不是类的实例构造函数。您的i变量的生命周期和范围与您班级的Type实例(也称为静态实例)相关联。

因此,无论何时第一次初始化您的课程,您都可以在此处调用ReplaceCC方法,这是一系列事件:

  1. 调用实例构造函数。
  2. 调用静态构造函数 - 它初始化静态i变量。
  3. 然后,当我已经实例化并初始化时,在对象实例上调用ReplaceCC方法。
  4. 您还可以查看我的想法中的this回答。

答案 3 :(得分:-2)

public string ReplaceCC(Match m)
{ 
    i++;//Here your adding 1 to the existing value
    return i.ToString() + i.ToString();     
} 

public static int i=0;//Here u declared and applied value, this is  declared when your class get instanciated

请查看评论