Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.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
.net 为什么单例类应该被密封?_.net_Design Patterns_Singleton_Class Design_Sealed - Fatal编程技术网

.net 为什么单例类应该被密封?

.net 为什么单例类应该被密封?,.net,design-patterns,singleton,class-design,sealed,.net,Design Patterns,Singleton,Class Design,Sealed,我想知道为什么一个单例类应该被密封。如果我们将构造函数作为私有的,我们可以阻止类被派生,对吗?。。下面我将粘贴MSDN中的几行。请给我一些颜色 在这种策略中,实例是在第一次引用类的任何成员时创建的。公共语言运行库负责变量初始化。类被标记为密封的,以防止派生,这可能会添加实例。有关将类别标记为密封类别的利弊讨论,请参见[Sells03]。此外,变量被标记为readonly,这意味着它只能在静态初始化期间(如图所示)或在类构造函数中赋值 这是一种设计指南,很明显,你可以遵循也可以不遵循。这只是标记您

我想知道为什么一个单例类应该被密封。如果我们将构造函数作为私有的,我们可以阻止类被派生,对吗?。。下面我将粘贴MSDN中的几行。请给我一些颜色

在这种策略中,实例是在第一次引用类的任何成员时创建的。公共语言运行库负责变量初始化。类被标记为密封的,以防止派生,这可能会添加实例。有关将类别标记为密封类别的利弊讨论,请参见[Sells03]。此外,变量被标记为readonly,这意味着它只能在静态初始化期间(如图所示)或在类构造函数中赋值


这是一种设计指南,很明显,你可以遵循也可以不遵循。这只是标记您的设计意图,就像基类将其标记为
抽象
,以避免将来可能出现的混乱。

sealed关键字意味着该类不能从中继承。声明构造函数为private意味着无法创建类的实例

这不是一回事。您可以拥有一个带有私有构造函数的基类,但仍然可以从该基类继承,定义一些公共构造函数,并有效地实例化该基类

请记住,构造函数不是继承的(因此派生类不会有所有私有构造函数,因为基类有),并且派生类总是首先调用基类构造函数。将类标记为密封的可以防止有人对精心构造的单例类进行琐碎的操作,因为这样可以防止有人从类继承

如果我们将构造函数作为私有的,我们可以阻止类被派生,对吗

不完全是:

这是因为
private
访问仅限于该类型的程序文本,包括嵌套类型。因此,
cursefoiledreach
可以访问
NotReallySingleton
的私有构造函数


但即使撇开这一点不谈,如果您的意图是没有人可以从该类派生,那么为什么不希望通过
sealed
尽可能清楚地表明该意图呢?

只有当派生类可以访问私有构造函数时,您才能从基类派生。请参阅我的答案,了解唯一可行的方法。但是,我无法构建以下代码类基类{private BaseClass(){}}classe Derrived:BaseClass{public void Display(){Console.WriteLine(“in Derrived class”);}我得到了类似于BaseClass的错误。BaseClass()由于其保护而不可访问level@JonSkeet为什么会有人从你的班级中衍生出来?这是不寻常的情况。如果有人可以编辑您的类,他们还可以添加公共参数化构造函数。插入构造函数应该比插入完整类容易。@DeepakMishra:一般来说,这样做有很好的理由,例如中的好代码。但更重要的是,这个问题断言所有构造函数都是私有的会阻止派生,答案反驳了这个断言。这是否是一个好主意与断言是否有效是分开的。@JonSkeet-hmm,你是对的,这个问题需要这个答案。
public class NotReallySingleton
{
    private NotReallySingleton() {}

    public class CursesFoiledAgain : NotReallySingleton
    {
    }
}

...

NotReallySingleton x = new CursesFoiledAgain();
NotReallySingleton y = new CursesFoiledAgain();