抽象基类强制每个派生类都是 Singleton
如何创建一个抽象类来强制每个派生类都是 Singleton ?我使用 C#。
How do I make an abstract class that shall force each derived classes to be Singleton ? I use C#.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这是行不通的,因为单例需要在某个地方进行静态访问,并且不能强制这样做。
有关单例实现 + 示例,请参阅:在 C# 中实现单例模式
that would not work because the singleton needs somwhere a static access and that can not be forced.
for singletonimplemention + examples see: Implementing the Singleton Pattern in C#
当您想要进行编译时检查时,这是不可能的。通过运行时检查,您可以做到这一点。这并不漂亮,但这是可能的。这是一个例子:
When you want to enfore compile time checking, this is not possible. With runtime checking you can do this. It's not pretty, but it's possible. Here's an example:
Singleton 意味着拥有私有构造函数。但你知道私有成员不能被继承。 C++ 中有模板,因此您可以从模板类创建单例。在 C# 中,没有模板,因此您必须为每个所需的单例编写自己的私有构造函数。
Singleton means having private constructors. But you know private members cannot be inherited. In C++ there were templates, so you could create a singleton from a template class. in C#, there aren't templates, so you have to write your own private constructors for every singleton you want.
java 或 C# 中的类不是“一流的”。类的静态部分不能被子类继承或覆盖。有关更多详细信息,请参阅此答案。另外,您没有元类的概念。
在 Smalltalk 或 Ruby 等语言中,您可以定义一个新的元类
Singleton
,它定义了一个方法getInstance
。然后,您可以将ClassA
和ClassB
定义为Singleton
元类的实例。然后,这两个类都会自动公开一个方法getInstance
,该方法可用于创建实例objectA
或objectB
。这不是很酷吗?嗯,在实践中,您不会经常使用元类,而单例实际上是我所知道的唯一有意义的用法。Classes in java or C# are not "first-class". The static part of a class can not be inherited or overridden by subclasses. See this answer for more details. Plus, you don't have a concept of meta-class.
In languages like Smalltalk or Ruby, you can define a new metaclass
Singleton
which defines a methodgetInstance
. Then you can defineClassA
andClassB
be instances of theSingleton
metaclass. Then both classes automatically expose a methodgetInstance
which can be used to create instancesobjectA
orobjectB
. Isn't that cool? Well, in practice you don't use metaclass frequently, and the singleton is actually the only usage of them that makes sense and that I'm aware of.这是一种(丑陋的)方法来做到这一点。它可能可以简化和改进,但这是我第一次尝试。
这个想法是首先使基类成为通用抽象类(如上面的注释中提到的),但类型参数被限制为从基类本身派生。这允许基类处理派生类型的单例实例。请注意,所有派生类都应密封,就像任何单例类一样。
接下来,允许使用受保护的构造函数,但需要接受特殊类 SingletonKey 的实例,该类是经过修改的单例。派生类可以访问 SingletonKey 类定义,但基类保留对唯一允许的实例的私有控制,从而保留对所有派生对象的构造的私有控制。
第三,基类需要能够调用派生类的构造函数,但这有点棘手。如果您尝试调用派生键控构造函数,编译器会抱怨,因为不能保证它存在。解决方案是添加派生类必须初始化的静态委托。因此任何派生类都需要提供一个简单的初始化方法。在代码中首次尝试访问实例之前,应显式调用此初始化方法,否则将导致运行时错误。
Here's an (ugly) way to do this. It could probably be simplified and improved, but it's my first go at it.
The idea is to first make the base class a generic abstract class (as mentioned in comments above), but the type parameter is constrained to derive from the base class itself. This allows the base class to handle the singleton instance of the derived type. Note all derived classes should be sealed, as with any singleton class.
Next, a protected constructor is allowed, but is required to accept an instance of a special class, SingletonKey, which is a modified singleton. Derived classes have access to the SingletonKey class definition, but the base class retains private control over the only allowed instance, and thus over construction of all derived objects.
Third, the base class will need to be able to call the constructor of the derived class, but this is slightly tricky. The compiler will complain if you try to call the derived keyed constructor, since it isn't guaranteed to exist. The solution is to add a static delegate that the derived class must initialize. So any derived classes will need to provide a simple initialization method. This initialization method should be called explicitly before attempting to access the instance for the first time in code, or a runtime error will result.
我相信我试图实现类似的目标,即在一组类上强制执行通用接口和单例模式。这是我的解决方案:
这是一个简单的测试:
请注意,如果您只需要基本的“模板”,您可以轻松地从通用抽象单例类中删除公共接口。
I believe I tried to achieve something similar i.e. enforce a common interface and the singleton pattern on a group of classes. This was my solution:
Here is a simple test:
Please note that you can easily remove the common interface from the generic abstract singleton class if you just need the basic "template".
这是我的单例继承的实现:
Here my implementation of Singleton inheritance: