如何在C#中使用全局变量?


Answers:


123

C#你不能确定真正的全局变量(在这个意义上,他们不属于任何类)。

话虽如此,我知道模仿此功能的最简单方法是使用static class,如下所示:

public static class Globals
{
    public const Int32 BUFFER_SIZE = 512; // Unmodifiable
    public static String FILE_NAME = "Output.txt"; // Modifiable
    public static readonly String CODE_PREFIX = "US-"; // Unmodifiable
}

然后,您可以在代码中的任何位置检索定义的值(只要它是同一代码的一部分namespace):

String code = Globals.CODE_PREFIX + value.ToString();

为了处理不同的名称空间,您可以:

  • 声明Globals该类而不将其包含在特定类中namespace(以便将其放置在全局应用程序名称空间中);
  • 插入适当的using指令来从另一个检索变量namespace

@Zarathos的类也必须是静态的吗?
kosnkov

4
好吧,这不是必需的,但我不明白为什么要实例化它。
Tommaso Belluzzo 2015年

如果您必须实例化其定义而不是“全局”,则不属于应用程序状态的一部分
Viking

嗨,如果我不在课堂上输入static关键字,会有什么区别?我只将字符串FILE_NAME设为静态,但尝试了一下,它仍然对我有用。
Tomer Cahal

1
没有static属性,您的类将是可实例化的(Globals g = new Globals())。它不会改变内部声明的静态变量的行为,但看起来并没有真正的用处。
Tommaso Belluzzo

74

C#中没有像全局变量这样的东西。期。

如果需要,可以具有静态成员:

public static class MyStaticValues
{
   public static bool MyStaticBool {get;set;}
}

虽然我同意,但您能否继续说明为什么C#中没有全局变量?我试图考虑一个很好的理由,为什么static您提供的示例不能真正被视为全局变量。
cregox

3
@cawas是因为“全局变量”的概念(从任何地方悬挂,浮空,不属于任何类)与OOP的本质背道而驰。C#严格是面向对象的。
Federico Berasategui 2013年

是的,这就是我同意的全部概念。但是通过创建该静态成员,您仅创建了一种全局变量。与您所说的不存在的全局变量有何不同?我想看一个实际的例子。
cregox

1
我觉得您是在回避我的问题,还是不清楚。但是我已经知道了。此处:stackoverflow.com/a/20010543/274502
cregox

7
现在,我意识到我的意思是静态成员在概念上和实际上都是全局var(除非是堆对象否则除非您正在编写不安全的代码或与非托管代码进行某种繁重的互操作,否则这只会有所作为)。所以我不知道为什么有人会说“ csharp中没有全局变量之类的东西 ”。这让我很困惑。
cregox

23

首先检查您是否真的需要全局变量,而不是公然使用它而不考虑您的软件体系结构。

假设它通过了测试。根据使用情况,Globals可能很难通过种族条件和许多其他“坏事”进行调试,最好从准备处理此类坏事的角度着手进行处理。所以,

  1. 将所有此类Global变量包装到一个static类中(出于可管理性)。
  2. 使用属性而不是字段(=“变量”)。这样,您便拥有了一些机制来解决将来与并发写入Globals的任何问题。

该类的基本轮廓为:

public class Globals
{
    private static bool _expired;
    public static bool Expired 
    {
        get
        {
            // Reads are usually simple
            return _expired;
        }
        set
        {
            // You can add logic here for race conditions,
            // or other measurements
            _expired = value;
        }
    }
    // Perhaps extend this to have Read-Modify-Write static methods
    // for data integrity during concurrency? Situational.
}

其他类的用法(在同一名称空间中)

// Read
bool areWeAlive = Globals.Expired;

// Write
// past deadline
Globals.Expired = true;

4

一个有用的功能是 using static

正如其他人所说,您必须为全局变量创建一个类:

public static class Globals {
    public const float PI = 3.14;
}

但是您可以像这样导入它,以便不再在其静态属性前面编写类名:

using static Globals;
[...]
Console.WriteLine("Pi is " + PI);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.