我想创建一个静态类或单例类,它接受在其构造函数中对另一个对象的引用.静态类已经出来了,但我想我可以创建一个在其构造函数中接受参数的单例.到目前为止,我没有任何运气搞清楚或谷歌搜索语法.这可能吗?如果是的话,我该怎么做?
对不起,在最初的帖子中没有任何例子,我匆匆写了.我觉得我的回答已经在回复中了,但这里有一些关于我想做的事情的澄清:
我想创建一个特定类型的单个实例(表示Singleton),但该类型的单个实例需要保存对不同对象的引用.
例如,我可能想要创建一个Singleton"Status"类,它拥有一个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
}
}
Run Code Online (Sandbox Code Playgroud)
在整个代码中,我检索我的状态单例并调用其UpdateMessage()方法.
private Status _status = Status.Instance; // + pass reference to GraphicsDevice
_status.UpdateMessage("Foo!");
Run Code Online (Sandbox Code Playgroud)
然后,在我的主类中,我还检索单例,并绘制它:
_status.Draw();
Run Code Online (Sandbox Code Playgroud)
是的,这意味着无论我在哪里检索单例,我都需要通过传入对GraphicsDevice的引用来实现,以防它是第一次实例化Singleton.我可以/将使用不同的方法来检索像我的Singleton类中的GraphicsDevice一样基本的东西,例如在其他地方注册服务并在Status类中获取该服务.这个例子非常人为 - 我试图弄清楚这种模式之类的东西是否可行.
And*_*are 17
这通常被认为是一个坏主意,因为如果您要接受对象引用或计划包装在类似单身包装器中的类型参数,则无法保证在AppDomain中保留该类型的唯一实例.
单例模式的重点是控制一个类型的单个实例,以便只存在该类型的一个实例.如果允许传入实例,或者如果您创建通用单例提供程序,则无法保证您的实例是唯一的实例.
假设我有一个SingletonFactory<T>允许我在我传递给工厂的任何类型周围创建一个单例.这将非常方便,并允许我做这样的事情:
SingletonFactory<Foo>.Instance;
Run Code Online (Sandbox Code Playgroud)
但是什么阻止了我这样做:
Foo foo = new Foo();
Run Code Online (Sandbox Code Playgroud)
糟糕,它看起来Foo不再是单身,因为我可以根据自己的意愿创建尽可能多的实例.为了使单例模式起作用,您需要能够完全控制需要限制其实例的类型.这就是为什么你不应该使用像我这样的东西SingletonFactory<T>.
注意: 对于接受对象实例的非泛型单例也是如此.我相信你可以从我之前的例子中推断出许多类似的原因,为什么接受单个包装器和对象引用也是个坏主意.
您所描述的是通用单例。它看起来像这样:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
http://www.codeproject.com/KB/cs/genericsingleton.aspx