全局变量的定义/初始化:通用实践? (面向C#)

时间:2010-09-09 12:37:39

标签: c# initialization global-variables declaration

我几天前发布了一个类似的问题,但这更适合任何* .Designer.cs文件。这个问题适用于类中全局变量的声明和初始化。据我所知,几乎常见的做法(除了* .Designer.cs文件之外)将所有全局变量放在类定义的开头,然后是任何顺序的其余代码(我更喜欢Getters和Setters,然后是构造函数,然后是事件,然后是misc函数)。好吧,我已经看到它已经完成并且已经完成了它,其中一个全局变量被设置为声明。

我不是指:

ClassA clA = new ClassA();

我指的是:

private int nViewMode = (int)Constants.ViewMode.Default;

现在,我听到有人说,我可以在某些层面上同意它,这些变量的初始化,那些在声明变量时不需要new语句的变量,应该是在构造函数或初始化函数中完成。但是,当他们说明这一点时,他们可能意味着之前的陈述没有问题,但不是以下内容:

错误的方式

private int nTotal = 100;
private int nCount = 10;
private int nDifference = nTotal - nCount;

可能正确的方式

private int nTotal = 100;
private int nCount = 10;
private int nDifference = 0;

void ClassConstructor()
{
  nDifference = nTotal - nCount;
}

我的问题是:

在这种情况下,最常见/标准的做法是什么? 两者的优点和缺点是什么? 这些问题是否只与某些语言有关而不是其他语言?

我想到的最后一个问题,因为我正在打字,这就是原因。在Visual Studio 2008中,似乎我可以在全局变量声明中放置断点,而我在大学时曾经不习惯编写C ++。另外,我相信在大学里,你不能使用在当前变量之前立即声明的变量,但是再次,那就是在C ++中。所以我不确定这些问题是否仅适用于MSVS产品(我们在大学时使用过Borland),更新的编译器,还是没有。如果有人有任何见解,我们表示赞赏。感谢。

4 个答案:

答案 0 :(得分:2)

我相信以前已经多次介绍过这个问题,但除了你做的最后做的事情之外,确实没有答案:确保它与你项目中其他地方的代码保持一致。

个人更喜欢在构造函数之外初始化默认值,除非根据使用的构造函数计算它们的方式不同。这样,如果出现另一个构造函数,则无需重复初始化代码。

在nDifference的情况下,也许封装逻辑的Property会更有意义:

  1. 如果没有使用它,则每次创建类的新实例时都不需要计算nDifference。
  2. 它表示无论使用哪种构造函数,nDifference的逻辑应始终相同。

答案 1 :(得分:1)

就个人而言,我喜欢初始化成员变量的能力,我在C#中声明它们,特别是如果你要写一个显式构造函数的唯一原因是初始化它们。

在较旧的C#方言中(我仍然在2.0工作的地方),我想如果你在构造函数中填充成员Dictionary<T>或某些东西,那么会有一个一致性参数,因为新的初始化器语法没有' t出现到以后。在这种情况下,您可以创建要将所有初始化保持在一起的参数。同样,如果你正在基于构造函数参数初始化一些成员,那么将所有初始化保持在一起而不是在构造函数中指定它所声明的东西和其他东西更有意义 - 但是如果你有多个构造函数,你不要重复自己,你最终会在一个地方进行一些初始化而其余的都在另一个地方,所以你可能最好在你声明它们的地方进行分配。

答案 2 :(得分:1)

我更喜欢初始化构造函数中的所有字段而不是声明点。 (我对此做的唯一例外是静态字段,我发现添加了静态构造函数的过度杀伤。)我的理由是我喜欢将所有构造逻辑放在一个地方,其次是为了避免调试器在混乱时跳转。单步执行代码。然而,这只是我的偏好,你可以自由地提出你最熟悉的约定。

正如其他人已经说过的那样,仔细考虑你的惯例并一致地应用它。

答案 3 :(得分:1)

C#语言定义保证字段初始化将在每个编译单元(文件)中以文本顺序发生。这意味着在静态字段声明的变量初始化程序中包含复杂表达式是完全可以的。 (另一方面,实例字段不能引用其他实例字段。)

如果字段的初始值取决于之前的值,那么它们可能应该保持在一起以避免意外重新排序。

class Demo1 {
    static int x = y + 10;  // x == 10
    static int y = 5;
}

class Demo2 {
    static int y = 5;
    static int x = y + 10;  // x == 15
}

正如其他人所说,我更希望在声明中出现所有实例(无论选择的构造函数如何)共有的初始化器。

此重新排序行为仅适用于静态变量初始值设定项。在编译时进行常量初始化,并按照确保正确初始化值的顺序计算值(并且不允许循环引用常量,不允许使用变量)。

class Demo3 {
    const int x = y + 10;  // Evaluated second. x == 15
    const int y = 5;       // Evaluated first.
}

您应该考虑是否需要存储计算值,因为在许多情况下,它可以在使用时计算。

class Demo4 {
    int y = 5;
    int x { get { return y + 10; } }
}