C#Singleton-基本实施和策略

时间:2018-11-30 18:26:16

标签: c#

一般来说,新的C#开发人员和程序员。我希望能深入了解Singleton的整体正确用法,并能正确访问类项目。我似乎无法弄清楚该如何正确完成。

背景

我正在使用MVVM开发C#WPF应用程序。

我的Singleton的目标是提供一个可全局访问的类,在那里我可以更新模型中的值。

使用以下语法在我的ViewModel顶部调用此Singleton:

public CurrentMDL_Singleton currentMDL_Singleton = CurrentMDL_Singleton.Instance;

我的一个ViewModel包含以下类:

public class CurrentMDL_Singleton
{
    private static CurrentMDL_Singleton instance;

    private CurrentMDL_Singleton()
    {
        CurrentMDL_Constructor currentMDL_Constructor = new CurrentMDL_Constructor();
    }

    public static CurrentMDL_Singleton Instance
    {
        get
        {
            if(instance == null)
            {
                //Create a new instance
                instance = new CurrentMDL_Singleton();
            }
            return instance;
        }
    }
}

知识检查:

我打算使用此Singleton创建“ currentMDL_Constructor”的实例。 currentMDL_Constructor是同一ViewModel中存在的另一个类,如下所示:

public class CurrentMDL_Constructor
{
    public Microsoft.Office.Interop.Excel.Application CurrentMDL_Excel { get; set; }
    public Microsoft.Office.Interop.Excel.Workbook CurrentMDL_Workbook { get; set; }
    public Microsoft.Office.Interop.Excel.Worksheet CurrentMDL_Worksheet { get; set; }
    public Microsoft.Office.Interop.Excel.Range CurrentMDL_xlRange { get; set; }
}

问题:

我无法访问由Singleton创建的currentMDL_Constructor实例,因为Singleton构造函数是私有成员(鉴于Singleton的用途,这是可以理解的)。

在我的模型中,我试图利用currentMDL_Constructor进行如下操作:

CurrentMDL_Excel = new Microsoft.Office.Interop.Excel.Application();
CurrentMDL_Workbook = CurrentMDL_Excel.Workbooks.Open(MainWindow.MDL_Compare_VM.CurrentMDL_File);

我什至无法考虑访问CurrentMDL_Constructor类,都无法访问currentMDL_Constructor。

我不了解什么?我感觉自己迷失在实例化,嵌套类,缺少有关Singleton用法和面向对象的基本知识的世界中。

在此先感谢您,如果此帖子多余,我深表歉意(找不到帮助我的帖子)。

-克里斯

3 个答案:

答案 0 :(得分:3)

您的代码有多个问题:

首先,在编写不依赖于其他类的单例(如您的情况)时,最佳实践是拥有一个静态的只读字段来保存单个实例,但是您应该像这样直接实例化它:

private static CurrentMDL_Singleton instance = new CurrentMDL_Singleton();

这是因为,每当引用单例类时,您都可能会使用其实例。将实例移动到字段init会将其移动到类型加载器中,因此使其成为线程安全的。在您的代码中,如果客户端并行访问Instance属性,则您可能会陷入竞争状态,因此会遇到单例类的两个不同实例,这通常是您要避免的。

第二,您的构造函数将创建一个对象,并且不会将其保存在任何地方,因此您将无法访问它。

第三,绝对不需要拥有单个实例的实例变量,因为您始终可以从静态实例字段中获取它。对于您而言,这甚至很危险,因为有人可以将其更改为null,并且您不会注意到。

最后,您应该重新考虑它是否真的是您需要的单例。应用单例模式来确保一个类只有一个实例,通常不是因为它更容易查询其内容,因为它是一个依赖关系,您不能轻易交换。

答案 1 :(得分:1)

通过公共属性Private Sub btnAction_Click(sender As Object, e As EventArgs) Handles btnAction.Click Dim input As String = txtIn.Text txtOut.Text = "No" For i As Integer = 0 To lstRoseBowl.Items.Count - 1 If input = CStr(lstBox.Items(i)) Then txtOut.Text = "Yes" Exit For End If Next End Sub 访问单例。

按如下方式访问Instance字段:

CurrentMDL_Constructor

答案 2 :(得分:0)

感谢所有对此提供帮助的人。我能够找出问题的主要出处,这与Singleton类的布局有关。

我想提到我使用此Singleton类的理由。我需要确保这些Excel变量只有一个实例存在。这很重要,因为我的ViewModel和Model依赖于引用相同项目的实例。由于混合实例,我一直在努力关闭这些Excel文件。这些Excel文件非常大,需要在应用程序功能之间保持打开状态,并在第二个功能之后直接关闭。 Singleton设计模型解决了确保单个实例的问题,并且使我能够轻松地从Model内部访问实例。

知识检查: 我错了的地方:

我以前的理解是,在实例化Singleton之后,Singleton类中的私有构造函数将设置我需要引用的内容。这是错误的想法。

不要使用私有构造函数实例化或引用任何东西;这与Singleton类的主要用法背道而驰。我们要做的就是确保仅存在该Singleton的一个实例; pivate构造函数在那里可以单独创建Singleton实例以供以后引用。

修复:

删除“ CurrentMDL_Constructor”类,将我试图为其创建引用的该类中的 项拖入Singleton主类。

public class CurrentMDL_Singleton
{
    public Microsoft.Office.Interop.Excel.Application CurrentMDL_Excel { get; set; }
    public Microsoft.Office.Interop.Excel.Workbook CurrentMDL_Workbook { get; set; }
    public Microsoft.Office.Interop.Excel.Worksheet CurrentMDL_Worksheet { get; set; }
    public Microsoft.Office.Interop.Excel.Range CurrentMDL_xlRange { get; set; }

    private static CurrentMDL_Singleton instance = null;

    private CurrentMDL_Singleton() {}

    public static CurrentMDL_Singleton Instance
    {
        get
        {
            if(instance == null)
            {
                //Create a new instance
                instance = new CurrentMDL_Singleton();
            }
            return instance;
        }
    }
}
现在可以通过调用Singleton中的实例(感谢上帝)来访问

CurrentMDL_Excel CurrentMDL_Workbook CurrentMDL_Worksheet 等。在我的模型中,我现在可以执行以下操作:

> CurrentMDL_Singleton.Instance.CurrentMDL_Excel = new Microsoft.Office.Interop.Excel.Application();

下一步是使Singleton线程安全。

再次感谢您的帮助,希望对其他了解如何实现Singleton的人有所帮助。

-克里斯