C# 单身过度使用

C# 单身过度使用,c#,winforms,singleton,C#,Winforms,Singleton,我曾考虑在我正在开发的winforms应用程序中使用单例模式,但很多人似乎认为单例是邪恶的。我正计划做一个“主菜单”的形式,这是一个单身。我想不出任何理由,我希望我的主菜单有多个实例,而且它总是第一个出现的形式,所以如果它被不必要地实例化,我不担心浪费资源 此外,如果主菜单有多个实例,我可以看到出现的问题。例如,如果另一个表单有一个“主菜单”按钮,并且主菜单有多个实例,那么显示哪个实例的决定似乎不明确 此外,如果我有另一个winform,它必须查看程序的状态,以确定是否已经存在主菜单的实例,那么

我曾考虑在我正在开发的winforms应用程序中使用单例模式,但很多人似乎认为单例是邪恶的。我正计划做一个“主菜单”的形式,这是一个单身。我想不出任何理由,我希望我的主菜单有多个实例,而且它总是第一个出现的形式,所以如果它被不必要地实例化,我不担心浪费资源

此外,如果主菜单有多个实例,我可以看到出现的问题。例如,如果另一个表单有一个“主菜单”按钮,并且主菜单有多个实例,那么显示哪个实例的决定似乎不明确

此外,如果我有另一个winform,它必须查看程序的状态,以确定是否已经存在主菜单的实例,那么我感觉我正在破坏模块化,尽管我可能是错的

在这种情况下,我应该避免使用单例还是让主菜单保持静态更好

我几天前才开始使用c#,在过去几年中我对OOP没有做太多的工作,所以如果这是一个愚蠢的问题,我很抱歉


谢谢大家喜欢全球国家。这显然很容易理解,对我们来说也很有意义。您不必担心使用的是哪个版本,因为它们都是相同的

然而,全局状态引入了各种各样的奇数错误,因此通常不鼓励这样做。C#做出了许多设计决策,使全局状态更难被忽略。例如,只允许将静态变量附加到必须管理它们的类

单身是获得这种全球状态的另一种方式,但它们的相似之处在于它们可能导致问题。如果您的一个屏幕设置了主菜单的一部分,然后切换到它,而没有意识到后台进程取消了更改,导致显示一个奇怪的主菜单,该怎么办

单例的另一个替代方法是确保变量到达需要的地方。一种方法是跟踪一堆菜单,实际上Android在下面就是这样工作的。每个UI都有一组位于其上方的父级,如果想要返回,可以切换到这些父级。通过确保只有初始引导过程创建初始主菜单屏幕,您可以保证只创建一个主菜单屏幕,但是所有屏幕仍然可以通过检查层次结构来访问它


此外,如果您谈论的是winforms,它们已经内置了一个层次结构系统,您可以使用它来提供此功能。

您几乎可以滥用任何东西

单例是一种保证在任何时候只有一个对象实例处于活动状态的方法,您可以同步对它的访问。对于静态类,您将失去这一点,因为任何人都可以随时访问静态类,所以您需要确保您的方法不会执行任何可能受并发性影响的操作

除此之外,如果我没看错的话,你需要一个表单,它是父表单,拥有菜单的唯一实例,所有其他表单都是这个表单的子表单。如果是这种情况,那么您应该检查Winforms中的MDI(多文档接口),因为这正好涵盖了您的场景


否则,我要做的就是为我的父窗体(带有主菜单的窗体)定义一个类,并让一个singleton expose accest访问它,然后为所有子窗体使用另一个基类。

是否始终显示
MainMenu
?如果没有,那么在旧实例关闭时释放它并在每次需要打开时创建一个新实例是有意义的。这样其他模块就不需要知道它的实例,只需要在需要打开它时创建一个。

您应该避免不必要的全局状态。单身只是这种状态发生的一种方式(但显然,这对一些人来说并不明显,所以他们在口头上说“globals=bad”)。静态变量也是全局变量。所以请不要把“单身汉是邪恶的”看成是表面上的;了解这些投诉针对的问题。在这一点上,我喜欢这篇文章。你也可能会发现值得一读。:)考虑到你了解单例(我从来没有发现过一种情况可以使用)和全局对象的问题,你是唯一可以决定是否使用它的人。顺便说一下,对比一下单例攻击:主要问题的必然结果是全局状态,单例(像其他全局状态的方式一样)不一定是坏的。当它只是包装一些已经(或本质上)是全局的东西(比如,操作系统提供的一些进程范围的状态,比如工作目录)并且因此不会引入比已经存在的状态更多的状态时,它不会造成任何伤害(至少w.r.t.全局状态的扩散)。但事实并非如此。静态变量不会使全局状态更难使用。这只是给全局变量命名的一种方法。@delnan:你不能只创建一个名为
numApples
的变量,这就是我所说的困难。在它前面添加
class{
(最后加一个右括号)是微不足道的。而且,由于几乎所有代码都必须在类/结构中,因此您手头上总是有一个类。实际上,该语言没有(有效)阻止全局状态(任何类型)。这可能是因为没有人希望它这样做,因为(1)正如其他答案所指出的,任何东西都可能被滥用,因此,不遗余力地“防止”坏代码没有什么意义,以及(2)相反,鼓励良好的做法更有效。谢谢,这似乎很合乎逻辑。出于某种原因,我想在我去另一个窗口时隐藏菜单,然后在我想回来时再次显示,但我不确定这个想法是从哪里来的。好吧,我有点意识到为什么我没有这么做。我真的很后悔当我导航到另一个菜单时,关闭主菜单时出现问题。当我放置