通过表格创建全局变量

时间:2018-08-23 23:30:57

标签: c# .net-4.0

我试图通过所有Windows窗体将用户名和一些其他信息另存为全局变量,这些窗体从我搜索过的userName之类的登录表单开始,并给出以下代码

首先,我创建一个名为globals的单独的类,如下所示:

public static class globals
{
    public static string userName { get; set; }
}

然后在登录成功后按如下所示设置该变量

Checks.globals.userName = TB_USER_NAME.Text;

几个问题

  • 我必须对用户名属性进行保护还是私有?

    public static string userName { get; private set; }
    
  • 是第一次初始化后将不会再次设置该值吗?

  • 还有什么好做的吗?

3 个答案:

答案 0 :(得分:5)

  

我正在尝试通过所有Windows窗体(从诸如UserName之类的登录窗体开始)将用户名和其他信息另存为全局变量

这被认为是C#中不良的编程实践。依赖全局状态会使您的程序更难以推理和修改。

考虑另一种方法;如果您的程序中有很多类实例需要访问相同的信息,则它们都可以保留对状态对象的引用,而不是对全局状态的引用。

  

首先,我创建一个名为globals的单独的类,如下所示:

如果您不愿意使用全局变量,那是正确的方法。但是您应该遵循C#标准并将其命名为Globals,而不是globals

类似地:

public static string userName { get; set; }

应为UserName,而不是userName

  

然后按如下所示在成功登录后设置该变量

Checks.globals.userName = TB_USER_NAME.Text;

同样,使用正确的C#命名约定。我们不在C#中使用SHOUTING_SNAKES_EVERYWHERE。

Checks.Globals.UserName = UserNameTextBox.Text;
  

我必须对用户名属性进行保护还是私有?

您不能使其受到保护;这是一个静态类!受保护意味着派生类可以访问,并且从静态类派生是非法的。

将其设置为私有将使它无法在班级外部访问,这与您想要的相反。

所以,不,不要那样做。您能解释一下为什么您认为这可能是个好主意吗?因为您有一些错误的信念,应该消除。

  

是第一次初始化后不会再次设置该值吗?

它将被设置为您设置的次数。 这就是全球状态的含义,以及为什么这是一个坏主意。现在,您必须确保程序只设置一次该值(如果需要的话),并且必须确保在程序中全局。这就是为什么全局状态不利于可维护性的原因:因为全局状态将适合本地分析的问题变成了需要整个程序分析的问题。

如果要检测设置了多个全局状态的错误,请使 more 全局状态:您需要“我的全局状态已设置一次”的全局状态。然后,您可以检查机器上的那个状态,如果程序被多次设置,则会使程序崩溃。或者,如果您想隐藏错误而不是修复错误,则忽略第二组或其他任何内容。

  

还有什么好做的吗?

是的。放弃需要您维护全局状态的体系结构。维护实例变量中的状态。

答案 1 :(得分:1)

这听起来像是您在问:“如何强制一次将变量设置一次”。在这种情况下,您可以创建一个后备字段来存储值,并且可以在属性set方法中首先检查该后备字段是否为null。如果是,请设置该值,否则请不要执行任何操作。以这种方式,仅一次设置了后备字段:

private static string _username = null;

public static string UserName
{
    get { return _userName; }
    set { if (_username == null) _username = value; }
}

另一种选择是将setter设为私有,并提供另一种设置值的方法。这造成了奇怪的设计,但确实使UserName属性为只读,这可以防止意外赋值(这会导致编译时错误)。

例如:

// UserName is a Read-Only property; it can't be assigned a value directly
public static string UserName { get; private set; }

// Anyone can change UserName here, but they have to intentionally call this method to do so
public static void SetUserName(string userName)
{
    UserName = userName;
}

答案 2 :(得分:1)

  

我必须对用户名属性进行保护还是私有?

如果您将属性userName设置为受保护或私有,则无法通过该属性设置值。

  

是第一次初始化后将不会再次设置该值吗?

取决于您的逻辑,因为它是全局值,所以需要小心。

  

还有什么更好的事情吗?

如果必须使用全局对象,则可以使用Singleton_pattern来创建全局对象。

当仅需要一个对象来协调整个系统中的动作时,这很有用。该概念有时被推广到仅存在一个对象的情况下运行效率更高的系统,或者将实例化限制为一定数量的对象的系统。

public class Globals
{
    private static Globals _obj;
    public static Globals Current {
        get {
            if (_obj == null)
                _obj = new Globals();
            return _obj;
        }
    }
    private Globals() { }

    private string _username;

    public string UserName { get { return _username; } }

    public void SetUserName(string userName) {
        this._username = userName;
    }
}

您可以使用Globals.Current获取全局对象。 如果您想设置UserName,只需调用SetUserName方法。

Globals.Current.SetUserName("test"); //set the username
Globals.Current.UserName; // get the username