带有接受参数的构造函数的 C# Singleton
Posted
技术标签:
【中文标题】带有接受参数的构造函数的 C# Singleton【英文标题】:C# Singleton with constructor that accepts parameters 【发布时间】:2010-11-10 12:13:18 【问题描述】:我想创建一个静态类或单例类,它在其构造函数中接受对另一个对象的引用。静态类已经出来了,但我想我可以创建一个在其构造函数中接受参数的单例。到目前为止,我还没有运气弄清楚或在谷歌上搜索语法。这可能吗?如果是这样,我该怎么做?
很抱歉在最初的帖子中没有示例,我写的很匆忙。我觉得我的答案已经在回复中,但这里有一些我想要做的澄清:
我想创建一个特定类型的单个实例(称为 Singleton),但该类型的单个实例需要保存对不同对象的引用。
例如,我可能想创建一个单例“状态”类,它拥有一个 StringBuilder 对象和一个可以调用的 Draw() 方法,以便将所述 StringBuilder 写入屏幕。 Draw() 方法需要了解我的 GraphcisDevice 才能进行绘制。 所以我想这样做:
public class Status
private static Status _instance;
private StringBuilder _messages;
private GraphicsDevice _gDevice;
private Status(string message, GraphicsDevice device)
_messages.Append(message);
_gDevice = device;
// The following isn't thread-safe
// This constructor part is what I'm trying to figure out
public static Status Instance // (GraphicsDevice device)
get
if (_instance == null)
_instance = new Status("Test Message!", device);
return _instance;
public void UpdateMessage
...
public void Draw()
// Draw my status to the screen, using _gDevice and _messages
在整个代码中,我检索了我的状态单例并调用它的 UpdateMessage() 方法。
private Status _status = Status.Instance; // + pass reference to GraphicsDevice
_status.UpdateMessage("Foo!");
然后,在我的主类中,我还检索单例,并绘制它:
_status.Draw();
是的,这意味着无论我在哪里检索单例,我都需要通过传入对 GraphicsDevice 的引用来这样做,以防这是我第一次实例化单例。而且我可以/将使用不同的方法来检索像我的 Singleton 类中的 GraphicsDevice 这样基本的东西,例如在其他地方注册一个服务并在 Status 类中获取该服务。这个例子非常做作 - 我试图弄清楚 something 这样的模式是否是可能的。
【问题讨论】:
添加了对我所问问题的更好解释。 【参考方案1】:我认为您具体要求的内容如下所示:
public sealed class Singleton
static Singleton instance = null;
static readonly object padlock = new Object();
Object o;
Singleton(Object _o)
o = _o;
public static Singleton Instance(Object _o)
lock (padlock)
if (instance == null)
instance = new Singleton(_o);
return instance;
Singleton s = Singleton.Instance(new Object());
不过,我怀疑已经发布的通用版本是您真正想要的。
【讨论】:
【参考方案2】:你可以做的一件事可能是坚持你找到的单例样本,只公开一个属性(setter,如果需要,也添加 getter)并像使用它一样使用它
MySingleton.Instance.MyReference = new MyObject();
如果你必须限制你的单例对象的使用,例如在设置引用之前对单例对象的任何操作都需要是非法的,你可以有一个私有的布尔标志,例如,hasBeenIntialized 和 MyReference setter 将在内部设置标志。所有其他方法将在执行开始时检查标志,并在 hasBeenInitialized 为 false 时调用任何方法时抛出异常。
如果您需要只读行为,如果有人想要在 hasBeenInitialized 设置为 true 时分配不同的对象,您可能会在 MyReference 设置器中抛出异常。
【讨论】:
【参考方案3】:这通常被认为是一个坏主意,因为如果您打算接受一个对象引用或一个类型参数,您计划包装在一个类似单例的包装器中,您不能保证您在应用程序域。
单例模式的全部意义在于控制一种类型的单个实例,以便该类型只能存在一个实例。如果您允许传入一个实例,或者如果您制作了一个通用的单例提供程序,则您不能保证您的实例是 only 实例。
假设我有一个SingletonFactory<T>
,它允许我围绕传递给工厂的任何类型创建一个单例。那会很方便,可以让我做这样的事情:
SingletonFactory<Foo>.Instance;
但是是什么阻止了我也这样做:
Foo foo = new Foo();
糟糕,Foo
看起来不再是单例了,因为我可以创建任意数量的实例。为了使单例模式起作用,您需要能够完全控制需要限制其实例的类型。这就是为什么你不应该使用像我的SingletonFactory<T>
这样的东西。
注意: 接受对象实例的非泛型单例也是如此。我相信您可以从我之前的示例中推断出许多类似的原因,为什么接受和对象引用的单例包装器也是一个坏主意。
【讨论】:
【参考方案4】:你需要一个私有的构造函数,然后是一个getInstance方法,这个方法是谁应该接收参数,构造函数必须是私有的,它也可以有参数,但是getInstance应该传递它,不是你。顺便说一句,你在做什么?一些真实的例子可能会有所帮助。
【讨论】:
【参考方案5】:您所描述的是通用单例。它看起来像这样:
public class SingletonProvider <T> where T:new()
SingletonProvider()
public static T Instance
get return SingletonCreator.instance;
class SingletonCreator
static SingletonCreator()
internal static readonly T instance = new T();
http://www.codeproject.com/KB/cs/genericsingleton.aspx
【讨论】:
如何保证你的应用程序中没有任何其他类型 T 的实例?这不是真正的单身人士。 我假设提出问题的人已经明白他不能将类型用于其他任何事情。他要了刀,我没有告诉他怎么处理。 Singleton以上是关于带有接受参数的构造函数的 C# Singleton的主要内容,如果未能解决你的问题,请参考以下文章
从 2.8.4 更新到 27.1.1 后,C# CsvWriter 抛出“CsvWriter 不包含接受 1 个参数的构造函数”