作为一个练习,我正在将我们庞大且经过强悍处理的Delphi框架的一部分翻译成C#。
此框架中包含一个通用的单例父类。当然,在C#中实现单例是相当容易的(甚至有一篇Jon Skeet文章,所以我还希望如此),但我们的Delphi单例对模式的看法略有不同:与发布'实例'相反property / method,它有一个“伪”构造函数,它总是返回相同的实例。这种方法的基本特征是单身类的用户不知道他正在处理单身人员: 据他们所知,他们只是构建任何旧类并从中请求一些信息。
我想在C#中完成同样的事情(作为一个练习,所以它不一定是生产质量的代码,邪恶的hackery很好),但到目前为止,我已经失败了。
任何建议让一个简单的myInstance = new MyClass();
总是返回相同的实例是非常受欢迎的!
我们正在谈论框架提供的单例模式的便利实现。它不一定必须是父类,但它也必须帮助开发人员创建自己的单例。要求他们手动将所有方法调用重定向到单实例,不会让他们满心欢喜。 : - )
我真的不想讨论这是否是处理单身人士的正确方法,因为现在我只对c#-tweaking的精细艺术感兴趣。
答案 0 :(得分:7)
你会做一个代理(编辑:正如汤姆在下面指出的那样,正确的设计模式是Monostate):
public class MyClass {
MyActualClass _actual;
public MyClass() {
_actual = MyActualClass. Instance;
}
public DoStuff() {
_actual.DoStuff();
}
}
internal class MyActualClass {
private MyActualClass {
}
public DoStuff() {
...
}
MyActualClass _instance;
public static Instance {
get {
if(_instance == null)
_instance = new MyActualClass()
return _instance;
}
}
}
...
public static void Main() {
var my1 = new MyClass();
var my2 = new MyClass();
}
my1!= my2但my1.DoStuff()调用与my2.DoStuff()相同的方法实例 如果您只编程了一个接口,这将进一步简化。
编辑:通过使_actual保护内部并覆盖MyClass.Equals(object obj)以检查this._actual == obj._actual
,可以部分解决相等问题答案 1 :(得分:4)
我相信Monostate模式可以满足您的需求:
“ Monostate为我们提供了我们在Singleton中如此珍惜的状态的奇点,但没有伴随它的所有静态头痛。”
答案 2 :(得分:2)
据我所知,由于C#如何处理对象实例,因此无法实现。为了调用构造函数,必须实际创建实例,并且不能只是从构造函数“返回”另一个对象。
我能想出的最好的东西(除了使用工厂方法)是将类内部视为Singleton,并创建“虚拟”实例,这些实例在创建时只指向原始实例。因此,例如,在构造函数中,您将检查单例是否已初始化,如果没有,将初始化它,那么您基本上只需将每个实例的方法和属性代理回单例。
在这个实现中,单例不一定必须是同一个类,但如果你想保持包含,你可以。
更新:这种方法的一个缺点是虽然每个实例都表现为作为单身,但它仍然有自己的对象引用,因此您可能也想要覆盖Equals()
进行相等比较。
答案 3 :(得分:0)
我不知道你怎么做,因为构造函数不使用return语句。你可以克隆到单例的所有相关链接,但它会有本地变量的本地副本,并且非常混乱。
而是让构造函数检查单例是否已实例化,如果已经实例化,则抛出异常,或者向使用旧样式代码的开发人员发出警告。
答案 4 :(得分:0)
我认为你可能会用Remoting推出一些东西。
<强>更新强>
更好的方法是在结构或轻量级类中包装一个合适的单例类。
答案 5 :(得分:0)
将单例创建为静态成员,并使所有方法访问单个静态实例。
class SingletonWrapper {
private static RealSingleton instance = new RealSingleton();
public void methodA() {
instance.methodA();
}
public String getA() {
return instance.getA();
}
}
(这实际上是Java代码,但我认为C#足够相似了。)
答案 6 :(得分:0)
如何使用静态函数返回对象而不是使用new关键字。
static private m_obj my_obj;
static private bool my_new_obj;
static public m_obj create_m_obj()
{
if (my_new_obj == false)
{
my_new_obj = true;
my_obj = new my_obj();
}
return my_obj;
}
如果我没有弄错的话,你可以轻松完全控制对象的创建。