C# - Winforms - 全局变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1293926/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# - Winforms - Global Variables
提问by Moon
I want some variables to be global across the project and accessible in every form. How can I do this?
我希望一些变量在整个项目中是全局的,并且可以以各种形式访问。我怎样才能做到这一点?
采纳答案by Wael Dalloul
yes you can by using static class. like this:
是的,您可以使用静态类。像这样:
static class Global
{
private static string _globalVar = "";
public static string GlobalVar
{
get { return _globalVar; }
set { _globalVar = value; }
}
}
and for using any where you can write:
并使用任何你可以写的地方:
GlobalClass.GlobalVar = "any string value"
回答by Rigobert Song
Or you could put your globals in the app.config
或者你可以把你的全局变量放在app.config 中
回答by user138894
public static class MyGlobals
{
public static string Global1 = "Hello";
public static string Global2 = "World";
}
public class Foo
{
private void Method1()
{
string example = MyGlobals.Global1;
//etc
}
}
回答by Micha? Ziober
You can use static classor Singleton pattern.
回答by Steve
One way,
单程,
Solution Explorer > Your Project > Properties > Settings.Settings. Click on this file and add define your settings from the IDE.
解决方案资源管理器 > 您的项目 > 属性 > Settings.Settings。单击此文件并从 IDE 添加定义您的设置。
Access them by
访问它们
Properties.Settings.Default.MySetting = "hello world";
回答by Steve
If you're using Visual C#, all you need to do is add a class in Program.cs inheriting Form and change all the inherited class from Form to your class in every Form*.cs.
如果您使用的是 Visual C#,您需要做的就是在 Program.cs 中添加一个继承 Form 的类,并将所有继承的类从 Form 更改为每个 Form*.cs 中的类。
//Program.cs
public class Forms : Form
{
//Declare your global valuables here.
}
//Form1.cs
public partial class Form1 : Forms //Change from Form to Forms
{
//...
}
Of course, there might be a way to extending the class Form without modifying it. If that's the case, all you need to do is extending it! Since all the forms are inheriting it by default, so all the valuables declared in it will become global automatically! Good luck!!!
当然,可能有一种方法可以在不修改 Form 的情况下扩展类 Form。如果是这种情况,您需要做的就是扩展它!由于所有的表单默认都继承了它,所以所有在其中声明的值都会自动成为全局的!祝你好运!!!
回答by J. Rodríguez
They have already answered how to use a global variable.
他们已经回答了如何使用全局变量。
I will tell you why the use of global variables is a bad idea as a result of this questioncarried out in stackoverflow in Spanish.
我会告诉你为什么使用全局变量是一个坏主意,因为这个问题是在西班牙语的 stackoverflow 中进行的。
Explicit translation of the text in Spanish:
西班牙语文本的明确翻译:
Impact of the change
变化的影响
The problem with global variables is that they create hidden dependencies. When it comes to large applications, you yourself do not know / remember / you are clear about the objects you have and their relationships.
全局变量的问题在于它们会创建隐藏的依赖关系。当涉及到大型应用程序时,您自己并不知道/记得/您清楚您拥有的对象及其关系。
So, you can not have a clear notion of how many objects your global variable is using. And if you want to change something of the global variable, for example, the meaning of each of its possible values, or its type? How many classes or compilation units will that change affect? If the amount is small, it may be worth making the change. If the impact will be great, it may be worth looking for another solution.
因此,您无法清楚地了解全局变量正在使用多少个对象。如果您想更改全局变量的某些内容,例如,每个可能值的含义或其类型?这种变化会影响多少类或编译单元?如果金额很小,可能值得进行更改。如果影响很大,可能值得寻找其他解决方案。
But what is the impact? Because a global variable can be used anywhere in the code, it can be very difficult to measure it.
但影响是什么?因为全局变量可以在代码中的任何地方使用,所以很难衡量它。
In addition, always try to have a variable with the shortest possible life time, so that the amount of code that makes use of that variable is the minimum possible, and thus better understand its purpose, and who modifies it.
此外,始终尝试拥有尽可能短的生命周期的变量,以便尽可能少地使用该变量的代码量,从而更好地了解其用途以及修改它的人。
A global variable lasts for the duration of the program, and therefore, anyone can use the variable, either to read it, or even worse, to change its value, making it more difficult to know what value the variable will have at any given program point. .
全局变量在程序运行期间持续存在,因此,任何人都可以使用该变量来读取它,或者更糟的是,更改它的值,这使得在任何给定程序中知道该变量将具有什么值变得更加困难观点。.
Order of destruction
破坏顺序
Another problem is the order of destruction. Variables are always destroyed in reverse order of their creation, whether they are local or global / static variables (an exception is the primitive types, int
,enum
s, etc., which are never destroyed if they are global / static until they end the program).
另一个问题是销毁的顺序。变量总是以其创建的相反顺序销毁,无论它们是局部变量还是全局/静态变量(一个例外是原始类型,int
,enum
s 等,如果它们是全局/静态的,则在它们结束程序之前永远不会被销毁) .
The problem is that it is difficult to know the order of construction of the global (or static) variables. In principle, it is indeterminate.
问题是很难知道全局(或静态)变量的构造顺序。原则上是不确定的。
If all your global / static variables are in a single compilation unit (that is, you only have a .cpp
), then the order of construction is the same as the writing one (that is, variables defined before, are built before).
如果你所有的全局/静态变量都在一个编译单元中(也就是说,你只有一个.cpp
),那么构造的顺序和写的一样(即之前定义的变量,都是在之前构建的)。
But if you have more than one .cpp
each with its own global / static variables, the global construction order is indeterminate. Of course, the order in each compilation unit (each .cpp
) in particular, is respected: if the global variableA
is defined before B
,A
will be built before B
, but It is possible that between A
andB
variables of other .cpp
are initialized. For example, if you have three units with the following global / static variables:
但是如果你有多个,.cpp
每个都有自己的全局/静态变量,全局构建顺序是不确定的。当然,在每个编译单元(each .cpp
)中的顺序尤其要尊重:如果全局变量A
是在之前定义的B
,那么A
会在之前构建B
,但是也有可能是其他的变量之间A
和B
变量.cpp
被初始化。例如,如果您有三个具有以下全局/静态变量的单元:
In the executable it could be created in this order (or in any other order as long as the relative order is respected within each .cpp
):
在可执行文件中,它可以按此顺序创建(或按任何其他顺序创建,只要在每个 中遵守相对顺序.cpp
):
Why is this important? Because if there are relations between different static global objects, for example, that some use others in their destructors, perhaps, in the destructor of a global variable, you use another global object from another compilation unit that turns out to be already destroyed ( have been built later).
为什么这很重要?因为如果不同的静态全局对象之间存在关系,例如,有些在其析构函数中使用其他对象,也许在全局变量的析构函数中,您使用来自另一个编译单元的另一个全局对象,结果证明已经被销毁(有后建造)。
Hidden dependencies and * test cases *
隐藏的依赖和 * 测试用例 *
I tried to find the source that I will use in this example, but I can not find it (anyway, it was to exemplify the use of singletons, although the example is applicable to global and static variables). Hidden dependencies also create new problems related to controlling the behavior of an object, if it depends on the state of a global variable.
我试图找到我将在此示例中使用的源,但我找不到它(无论如何,它是为了举例说明单例的使用,尽管该示例适用于全局和静态变量)。如果对象依赖于全局变量的状态,则隐藏的依赖项还会产生与控制对象行为相关的新问题。
Imagine you have a payment system, and you want to test it to see how it works, since you need to make changes, and the code is from another person (or yours, but from a few years ago). You open a new main
, and you call the corresponding function of your global object that provides a bank payment service with a card, and it turns out that you enter your data and they charge you. How, in a simple test, have I used a production version? How can I do a simple payment test?
假设您有一个支付系统,您想测试它以了解它是如何工作的,因为您需要进行更改,而代码来自另一个人(或您的,但来自几年前)。您打开一个新的main
,并调用提供银行支付服务的全局对象的相应函数,结果是您输入了数据,然后他们向您收费。在一个简单的测试中,我如何使用生产版本?如何进行简单的付款测试?
After asking other co-workers, it turns out that you have to "mark true", a global bool that indicates whether we are in test mode or not, before beginning the collection process. Your object that provides the payment service depends on another object that provides the mode of payment, and that dependency occurs in an invisible way for the programmer.
在询问其他同事后,结果表明您必须在开始收集过程之前“标记为真”,这是一个指示我们是否处于测试模式的全局布尔值。提供支付服务的对象依赖于提供支付方式的另一个对象,而这种依赖以一种对程序员不可见的方式发生。
In other words, the global variables (or singletones), make it impossible to pass to "test mode", since global variables can not be replaced by "testing" instances (unless you modify the code where said code is created or defined). global variable, but we assume that the tests are done without modifying the mother code).
换句话说,全局变量(或单调)使其无法传递到“测试模式”,因为全局变量不能被“测试”实例替换(除非您修改了创建或定义所述代码的代码)。全局变量,但我们假设测试是在不修改母代码的情况下完成的)。
Solution
解决方案
This is solved by means of what is called * dependency injection *, which consists in passing as a parameter all the dependencies that an object needs in its constructor or in the corresponding method. In this way, the programmer ** sees ** what has to happen to him, since he has to write it in code, making the developers gain a lot of time.
这是通过所谓的*依赖注入*解决的,它包括将对象在其构造函数或相应方法中所需的所有依赖项作为参数传递。这样,程序员**看到**他要发生什么,因为他必须用代码来编写,让开发人员获得了大量的时间。
If there are too many global objects, and there are too many parameters in the functions that need them, you can always group your "global objects" into a class, style * factory *, that builds and returns the instance of the "global object" (simulated) that you want , passing the factory as a parameter to the objects that need the global object as dependence.
如果全局对象太多,并且需要它们的函数中的参数太多,您总是可以将“全局对象”分组到一个类中,样式 * factory *,该类构建并返回“全局对象”的实例”(模拟)你想要的,将工厂作为参数传递给需要全局对象作为依赖的对象。
If you pass to test mode, you can always create a testing factory (which returns different versions of the same objects), and pass it as a parameter without having to modify the target class.
如果传递到测试模式,您始终可以创建一个测试工厂(它返回相同对象的不同版本),并将其作为参数传递,而无需修改目标类。
But is it always bad?
但它总是坏的吗?
Not necessarily, there may be good uses for global variables. For example, constant values ??(the PI value). Being a constant value, there is no risk of not knowing its value at a given point in the program by any type of modification from another module. In addition, constant values ??tend to be primitive and are unlikely to change their definition.
不一定,全局变量可能有很好的用途。例如,常数值??(PI 值)。作为一个常量值,不存在通过来自另一个模块的任何类型的修改而在程序中的给定点不知道其值的风险。此外,常量值往往是原始的,不太可能改变它们的定义。
It is more convenient, in this case, to use global variables to avoid having to pass the variables as parameters, simplifying the signatures of the functions.
在这种情况下,使用全局变量可以更方便地避免将变量作为参数传递,从而简化函数的签名。
Another can be non-intrusive "global" services, such as a logging class (saving what happens in a file, which is usually optional and configurable in a program, and therefore does not affect the application's nuclear behavior), or std :: cout
,std :: cin
or std :: cerr
, which are also global objects.
另一个可以是非侵入性的“全局”服务,例如日志记录类(将发生的事情保存在文件中,通常在程序中是可选的和可配置的,因此不会影响应用程序的核行为),或std :: cout
,std :: cin
或std :: cerr
,也是全局对象。
Any other thing, even if its life time coincides almost with that of the program, always pass it as a parameter. Even the variable could be global in a module, only in it without any other having access, but that, in any case, the dependencies are always present as parameters.
任何其他东西,即使它的生命周期几乎与程序的生命周期一致,也总是将它作为参数传递。甚至变量在模块中也可以是全局的,只有在模块中没有任何其他访问权限,但无论如何,依赖项始终作为参数存在。
Answer by: Peregring-lk
回答者:Peregring-lk
回答by Marlon Allan Supetran
The consensus here is to put the global variables in a static class as static members. When you create a new Windows Forms application, it usually comes with a Program class (Program.cs), which is a static class and serves as the main entry point of the application. It lives for the the whole lifetime of the app, so I think it is best to put the global variables there instead of creating a new one.
这里的共识是将全局变量作为静态成员放在静态类中。当您创建一个新的 Windows 窗体应用程序时,它通常带有一个 Program 类 (Program.cs),它是一个静态类,用作应用程序的主要入口点。它存在于应用程序的整个生命周期中,所以我认为最好将全局变量放在那里而不是创建一个新变量。
static class Program
{
public static string globalString = "This is a global string.";
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
And use it as such:
并使用它:
public partial class Form1 : Form
{
public Form1()
{
Program.globalString = "Accessible in Form1.";
InitializeComponent();
}
}