如何在没有全局变量的情况下保留数据?

时间:2022-06-08 20:22:44

I'm used to scripting languages. PHP, Javascript etc. and I've written a few relatively simple Java and C# apps. This is a question I've repeatedly needed an answer for, and I imagine I'm not the only one.

我习惯于编写脚本语言。 PHP,Javascript等,我写了一些相对简单的Java和C#应用程序。这是一个我一再需要答案的问题,我想我不是唯一一个。

Let's say I'm in Javascript.

假设我使用的是Javascript。

I have function A(), called by the GUI, which retrieves some value.

我有一个由GUI调用的函数A(),它检索一些值。

Function B(), also called by the GUI, requires that value, but function B() is going to be called an arbitrary number of times, an arbitrary length of time after A().

函数B(),也由GUI调用,需要该值,但函数B()将被调用任意次数,即A()之后的任意长度。

I don't want A() to recalculate the value every time.

我不希望A()每次重新计算值。

An example is logon credentials. A() asks for a username, and B() uses that value to append to a log every time it is called.

一个示例是登录凭据。 A()要求输入用户名,B()使用该值在每次调用时追加到日志中。

For this I would probably just use a global variable.

为此我可能只使用一个全局变量。

Now, C#. No global variables! How am I supposed to do this?

现在,C#。没有全局变量!我该怎么做?

Edit: Enjoying the answers, but there are a lot of "try not to use globals" comments. Which I do understand, but I'd like to hear the alternative patterns for this requirement.

编辑:享受答案,但有很多“尽量不使用全局”的评论。我明白了,但我想听听这个要求的替代模式。

5 个解决方案

#1


Firstly, always ask yourself if you really need to have a global, often you won't. But if you really have to have one...

首先,总是问自己,你是否真的需要一个全球性的,通常你不会。但如果你真的需要一个......

The best way to do this is to have a static property on some sensibly named class, it effectively becomes your global variable

执行此操作的最佳方法是在一些明确命名的类上使用静态属性,它实际上将成为您的全局变量

public class Credentials
{
  public static string Username {get;set;}
}

//...somewhere in your code

Credentials.Username = "MyUserName";

EDIT:

A couple people here have said the blanket statement that Global Variables are bad, and I do agree with this sentiment, and it would appear that the designers of C# also agree as they are simply not available.

这里的一些人已经说过全局变量不好的一揽子声明,我同意这种观点,看来C#的设计者也同意,因为它们根本不可用。

We should however look at the reasons why Globals are bad, and they are mostly regarded as bad because you break the rules of encapsulation. Static data though, is not necesarrily bad, the good thing about static data is that you can encapsulate it, my example above is a very simplistic example of that, probably in a real world scenario you would include your static data in the same class that does other work with the credentials, maybe a Login class or a User class or whatever makes sense to your app.

然而,我们应该看看为什么Globals是坏的,并且他们大多被认为是坏的,因为你违反了封装规则。静态数据虽然不是很糟糕,静态数据的好处在于你可以封装它,我上面的例子是一个非常简单的例子,可能在现实世界的场景中你将静态数据包含在同一个类中其他工作与凭证,可能是登录类或用户类或任何有意义的应用程序。

#2


This is not a good practice, but if you really need it, there is a number of ways:

这不是一个好习惯,但如果你真的需要它,有很多方法:

  1. Web apps: You can put your variable in some kind of context, like the session or the application scope.
  2. Web应用程序:您可以将变量放在某种上下文中,例如会话或应用程序范围。

  3. Desktop apps: You can create an object and store it as a property of a class that always have an object active.
  4. 桌面应用程序:您可以创建对象并将其存储为始终使对象处于活动状态的类的属性。

  5. Any kind of app: use a public static property. It is visible to everyone.
  6. 任何类型的应用程序:使用公共静态属性。每个人都可以看到它。

#3


I'd say you should probably use a Singleton Pattern.

我会说你应该使用Singleton模式。

If you're going for a multithreaded application then you need to also make sure accesses to the properties of the instance of the singleton are threadsafe.

如果您要使用多线程应用程序,那么您还需要确保对单例实例的属性的访问是线程安全的。

As always please think carefully about introducing any kind of global in your application but don't be affraid to use it. A lot of things are indeed globals, like the App.Settings for example without having anything "bad" in them.

一如既往,请仔细考虑在您的应用程序中引入任何类型的全局,但不要害怕使用它。很多事情确实是全局性的,例如App.Settings,其中没有任何“坏”。

This article on MSDN explains how to correctly create a singleton in c#.

MSDN上的这篇文章解释了如何在c#中正确创建单例。

#4


In C#, one of the ways to get behavior similar to global variables is to use static class methods and class variables. Static class methods and variables have a single instance in C#, and are somewhat akin to global variables in other languages.

在C#中,获取类似于全局变量的行为的方法之一是使用静态类方法和类变量。静态类方法和变量在C#中有一个实例,有点类似于其他语言中的全局变量。

That said, for your problem, it sounds much more like a design problem. C# is very focused on Object Oriented Design; I'd suspect for the problem you've given that a better OOD would resolve your problem.

也就是说,对于你的问题,它听起来更像是一个设计问题。 C#非常注重面向对象设计;我怀疑你给出的问题是更好的OOD可以解决你的问题。

#5


Function A would be part of a class (call it C). Function A could then store the logon credentials and provide a function (or in C#, a property) to obtain the credentials. When they are required, you can simply use the property to obtain the stored credentials and pass them into Function B (on a different class).

函数A将成为类的一部分(称为C)。然后,函数A可以存储登录凭据并提供函数(或在C#中,属性)以获取凭据。当需要它们时,您可以简单地使用该属性来获取存储的凭据并将它们传递到函数B(在不同的类上)。

class C
{
    public void functionA()
    {
         credentials = obtainCredentials;
    }

    private LogonCredentials _logonCredentials = null;

    public LogonCredentials logonCredentials
    {
        get { return _logonCredentials; }
    }
}

class D
{
    public void functionB(LogonCredentials credentials)
    {
       //do stuff
    }
}

///other stuff
///other function ...
    ...
    instanceC = C();
    instanceC.functionA();
    ///more stuff here
    instangeD = D();
    instanceD.functionB(instanceC.logonCredentials);

#1


Firstly, always ask yourself if you really need to have a global, often you won't. But if you really have to have one...

首先,总是问自己,你是否真的需要一个全球性的,通常你不会。但如果你真的需要一个......

The best way to do this is to have a static property on some sensibly named class, it effectively becomes your global variable

执行此操作的最佳方法是在一些明确命名的类上使用静态属性,它实际上将成为您的全局变量

public class Credentials
{
  public static string Username {get;set;}
}

//...somewhere in your code

Credentials.Username = "MyUserName";

EDIT:

A couple people here have said the blanket statement that Global Variables are bad, and I do agree with this sentiment, and it would appear that the designers of C# also agree as they are simply not available.

这里的一些人已经说过全局变量不好的一揽子声明,我同意这种观点,看来C#的设计者也同意,因为它们根本不可用。

We should however look at the reasons why Globals are bad, and they are mostly regarded as bad because you break the rules of encapsulation. Static data though, is not necesarrily bad, the good thing about static data is that you can encapsulate it, my example above is a very simplistic example of that, probably in a real world scenario you would include your static data in the same class that does other work with the credentials, maybe a Login class or a User class or whatever makes sense to your app.

然而,我们应该看看为什么Globals是坏的,并且他们大多被认为是坏的,因为你违反了封装规则。静态数据虽然不是很糟糕,静态数据的好处在于你可以封装它,我上面的例子是一个非常简单的例子,可能在现实世界的场景中你将静态数据包含在同一个类中其他工作与凭证,可能是登录类或用户类或任何有意义的应用程序。

#2


This is not a good practice, but if you really need it, there is a number of ways:

这不是一个好习惯,但如果你真的需要它,有很多方法:

  1. Web apps: You can put your variable in some kind of context, like the session or the application scope.
  2. Web应用程序:您可以将变量放在某种上下文中,例如会话或应用程序范围。

  3. Desktop apps: You can create an object and store it as a property of a class that always have an object active.
  4. 桌面应用程序:您可以创建对象并将其存储为始终使对象处于活动状态的类的属性。

  5. Any kind of app: use a public static property. It is visible to everyone.
  6. 任何类型的应用程序:使用公共静态属性。每个人都可以看到它。

#3


I'd say you should probably use a Singleton Pattern.

我会说你应该使用Singleton模式。

If you're going for a multithreaded application then you need to also make sure accesses to the properties of the instance of the singleton are threadsafe.

如果您要使用多线程应用程序,那么您还需要确保对单例实例的属性的访问是线程安全的。

As always please think carefully about introducing any kind of global in your application but don't be affraid to use it. A lot of things are indeed globals, like the App.Settings for example without having anything "bad" in them.

一如既往,请仔细考虑在您的应用程序中引入任何类型的全局,但不要害怕使用它。很多事情确实是全局性的,例如App.Settings,其中没有任何“坏”。

This article on MSDN explains how to correctly create a singleton in c#.

MSDN上的这篇文章解释了如何在c#中正确创建单例。

#4


In C#, one of the ways to get behavior similar to global variables is to use static class methods and class variables. Static class methods and variables have a single instance in C#, and are somewhat akin to global variables in other languages.

在C#中,获取类似于全局变量的行为的方法之一是使用静态类方法和类变量。静态类方法和变量在C#中有一个实例,有点类似于其他语言中的全局变量。

That said, for your problem, it sounds much more like a design problem. C# is very focused on Object Oriented Design; I'd suspect for the problem you've given that a better OOD would resolve your problem.

也就是说,对于你的问题,它听起来更像是一个设计问题。 C#非常注重面向对象设计;我怀疑你给出的问题是更好的OOD可以解决你的问题。

#5


Function A would be part of a class (call it C). Function A could then store the logon credentials and provide a function (or in C#, a property) to obtain the credentials. When they are required, you can simply use the property to obtain the stored credentials and pass them into Function B (on a different class).

函数A将成为类的一部分(称为C)。然后,函数A可以存储登录凭据并提供函数(或在C#中,属性)以获取凭据。当需要它们时,您可以简单地使用该属性来获取存储的凭据并将它们传递到函数B(在不同的类上)。

class C
{
    public void functionA()
    {
         credentials = obtainCredentials;
    }

    private LogonCredentials _logonCredentials = null;

    public LogonCredentials logonCredentials
    {
        get { return _logonCredentials; }
    }
}

class D
{
    public void functionB(LogonCredentials credentials)
    {
       //do stuff
    }
}

///other stuff
///other function ...
    ...
    instanceC = C();
    instanceC.functionA();
    ///more stuff here
    instangeD = D();
    instanceD.functionB(instanceC.logonCredentials);