一般来说,新的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用法和面向对象的基本知识的世界中。
在此先感谢您,如果此帖子多余,我深表歉意(找不到帮助我的帖子)。
-克里斯
答案 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的人有所帮助。
-克里斯