Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#应用程序中使用单例_C# - Fatal编程技术网

在C#应用程序中使用单例

在C#应用程序中使用单例,c#,C#,在stackoverflow和其他一些网站上,我花了几天时间阅读并尝试了创建和使用我的一个类文件的单例实例的不同方法,然后在程序的整个生命周期中使用我需要的引用,并发现有太多的意见,我有点困惑,特别是当涉及到实际使用singleton对象的时候,那些有用的建议和示例 我有一些功能,但我不认为这是最正确的方式,我可能错过了一步 我的程序中有一个名为clsRegistry的简单类文件,它作为一个单例实现 public sealed class clsRegistry { //http://tec

在stackoverflow和其他一些网站上,我花了几天时间阅读并尝试了创建和使用我的一个类文件的单例实例的不同方法,然后在程序的整个生命周期中使用我需要的引用,并发现有太多的意见,我有点困惑,特别是当涉及到实际使用singleton对象的时候,那些有用的建议和示例

我有一些功能,但我不认为这是最正确的方式,我可能错过了一步

我的程序中有一个名为clsRegistry的简单类文件,它作为一个单例实现

public sealed class clsRegistry
{
  //http://tech.pro/tutorial/625/csharp-tutorial-singleton-pattern

  private static clsRegistry RegInstance;

  private clsRegistry() { }

  public static clsRegistry GetInstance()
  {
    lock (typeof(clsRegistry))
    {
      if (RegInstance == null)
      {
        RegInstance = new clsRegistry();
      }
      return RegInstance;
    }
  }

  public string dataBase { get; set; }
  public string userId { get; set; }
  public string passWord { get; set; }

  public void ReadKeys()
  {
    //http://stackoverflow.com/questions/1388787/information-in-registry
    RegistryKey key = Registry.LocalMachine.OpenSubKey(@"Software\Key1\Key2\Key3");
    dataBase = key.GetValue("ADODataSource").ToString().Trim();
    userId = key.GetValue("ServerUserID").ToString().Trim();
    passWord = key.GetValue("ServerPassword").ToString().Trim();
  }
}   // end class definition
当从Main方法调用时,它将正确实现并调用类中的一个公共方法(ReadKeys)

static class Program
{
  /// <summary>
  /// The main entry point for the application.
  /// </summary>
  [STAThread]
  static void Main()
  {
    // create instance of registry class 
    clsRegistry regData = clsRegistry.GetInstance();

    // call method
    regData.ReadKeys();

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    //Application.Run(new frmMain());
    Application.Run(new frmLogin());
  }
}
我真的需要创建另一个对我的singleton对象的引用来读取一些值(或者稍后调用另一个方法)吗?或者我在哪里遗漏了一个步骤?我是在这样的假设下操作的:一旦我创建了一个类的实例作为一个单例,并且它保持在同一个名称空间中,我就可以访问任何公共值或方法。没有

作为参考,我使用的是Visual Studio 2010和4.0框架(是的,我是另一个终于跳槽的经典VB开发人员)

首先:在C中,你不需要锁等。只需通过静态初始化创建实例,就可以实现线程安全

public sealed class ClsRegistry
{
    private static ClsRegistry RegInstance = new ClsRegistry();

    private clsRegistry() { }

    public static ClsRegistry Instance {
        get { return RegInstance; }
    }

    public string DataBase { get; set; }
    public string UserId { get; set; }
    public string PassWord { get; set; }

    public void ReadKeys()
    {
        // ...
    }
}
话虽如此,您只需通过
ClsRegistry.Instance
访问singleton及其属性/方法,而无需首先将其分配给新变量:

static void Main()
{
    ClsRegistry.Instance.ReadKeys();
    // ...
}

请注意,我更改了类和属性的名称,使每个第一个字母都是大写,这在C#

中是一种惯例。首先,在C#中,不需要锁等。只需通过静态初始化创建实例,就可以实现线程安全

public sealed class ClsRegistry
{
    private static ClsRegistry RegInstance = new ClsRegistry();

    private clsRegistry() { }

    public static ClsRegistry Instance {
        get { return RegInstance; }
    }

    public string DataBase { get; set; }
    public string UserId { get; set; }
    public string PassWord { get; set; }

    public void ReadKeys()
    {
        // ...
    }
}
话虽如此,您只需通过
ClsRegistry.Instance
访问singleton及其属性/方法,而无需首先将其分配给新变量:

static void Main()
{
    ClsRegistry.Instance.ReadKeys();
    // ...
}


请注意,我更改了类和属性的名称,因此每个第一个字母都是大写,这在C#

中是一种约定,您需要询问singleton的引用以访问值,是的。如果不想,您不需要将该引用存储在局部变量中,尽管您当然可以。如果不想,可以直接从实例访问值:

lblDataBase.Text = clsRegistry.GetInstance().dataBase;

您需要向singleton请求其引用以访问这些值,是的。如果不想,您不需要将该引用存储在局部变量中,尽管您当然可以。如果不想,可以直接从实例访问值:

lblDataBase.Text = clsRegistry.GetInstance().dataBase;

首先,微软有一个专门在C#中实现单线程的方法,它详细解释了创建单线程和多线程单线程类的最佳方法

就您的代码而言:

  • 调用GetInstance时,您没有创建对象的另一个实例。代码返回先前创建的实例。如果类的新实例为null(仅一次),则它仅实例化该类的新实例

  • 您应该在.NET中将实例作为属性而不是方法(它只是更干净)

  • 在编写.NET代码时,您应该坚持使用Pascal大小写,如果您在编写Java代码,我建议您坚持使用camelCase,因为这是该语言的标准大小写


  • 首先,微软有一个专门在C#中实现单线程的方法,它详细解释了创建单线程和多线程单线程类的最佳方法

    就您的代码而言:

  • 调用GetInstance时,您没有创建对象的另一个实例。代码返回先前创建的实例。如果类的新实例为null(仅一次),则它仅实例化该类的新实例

  • 您应该在.NET中将实例作为属性而不是方法(它只是更干净)

  • 在编写.NET代码时,您应该坚持使用Pascal大小写,如果您在编写Java代码,我建议您坚持使用camelCase,因为这是该语言的标准大小写


  • 我认为你做得对。仅仅因为您已经创建了singleton对象的实例,并不意味着您应该能够在范围外使用对它的引用——它不是一个全局变量。如果您想在另一个类中使用该实例,您必须像这里一样获得对它的引用。您并没有创建一个“新”的单例,只是获取对现有单例的引用。至少这是我的理解。你不是在“创建”一个新实例,只是获取对单个实例的引用。如果你花了最后几天的时间阅读它,你一定是偶然发现的?根据我的理解,这是一个非常简洁的实现。请确保您不应该公开
    ReadKeys
    ,您应该只是在构造函数中初始化数据。您的属性也不应该有setter。最重要的是,你真的确定要在注册表中存储用户名和密码,这听起来不安全。我认为你做得对。仅仅因为您已经创建了singleton对象的实例,并不意味着您应该能够在范围外使用对它的引用——它不是一个全局变量。如果您想在另一个类中使用该实例,您必须像这里一样获得对它的引用。您并没有创建一个“新”的单例,只是获取对现有单例的引用。至少这是我的理解。你不是在“创建”一个新实例,只是获取对单个实例的引用。如果你花了最后几天的时间阅读它,你一定是偶然发现的?据我所知,这是一个非常简洁的实现。请务必阅读,您不应该公开
    ReadKeys
    publi