带有参数的构造函数的单例



我有一个带有参数的winform构造函数:

    public SnippingTool(Bitmap screenShot)
        {
            InitializeComponent();
            this.BackgroundImage = screenShot;
            ...
        }

当应用程序运行时,我只需要一个winform实例,所以我决定使用单例模式。

我发现了这个结构(由于我的类构造函数中的参数,它不适合(:

    private static SnippingTool instance;
    public static SnippingTool GetInstance
    {
        get
        {
            if (instance == null)
            {
                instance = new SnippingTool();
            }
            return instance;
        }
    }

如何通过单例传递参数?

如果位图每次都不同,并且您肯定只需要一个SnippingTool,那么也许位图甚至不应该有该工具的实例变量,那么位图肯定在构造函数中没有位置。

而是使位图成为在SnippingTool实例上调用的主要"操作"方法的参数。

或者,如果您需要SnippingTool将位图作为"状态"(因为它是一个表单,并且需要显示和编辑图像(,然后创建诸如SetImage(Bitmap b)ClearImage()等方法。

您还可以创建方法而不是属性。

private static SnippingTool _instance;
public static SnippingTool GetInstance(Bitmap screen)
{
    get
    {
        if (_instance == null || _instance.IsDisposed)
        {
            _instance = new SnippingTool(screen);
        }
        return _instance;
    }
}

试试这个

 private static SnippingTool instance;
 private SnippingTool (var par){
   ....
 }
 public SnippingTool createSingleton(var par){
   if instance != null 
               return instance;
   else 
      return new SnippingTool(par);
 }

如果此SnippingTool只能与一个BitMap实例一起使用,则没有理由始终将一个传递给单例属性/方法。这至少会令人困惑,因为调用者会认为他会得到一个用于此位图的工具。如果传递其他实例,该方法应引发异常。但这是否有意义,在我看来没有多大意义。

所以我会这样,实现一个SetScreenshotSetInstance的方法,例如:

public class SnippingTool
{
    private SnippingTool(Bitmap screenShot)
    {
        this.ScreenShot = screenShot;
    }
    private static SnippingTool instance;
    public static void SetScreenshot(Bitmap screenShot)
    {
        if (instance == null || instance.IsDisposed)
        {
            instance = new SnippingTool(screenShot);
        }
        else
        {
            // now your logic, is it allowed then overwrite the screenShot, otherwise:
            throw new ArgumentException("It's not allowed to change the screenShot for this SnippingTool", nameof(screenShot));
        }
    }
    public static SnippingTool GetInstance
    {
        get
        {
            if (instance == null)
                throw new Exception("The SnippingTool needs a screenShot first, use first " + nameof(SetScreenshot));
            return instance;
        }
    }
    public Bitmap ScreenShot { get; }
    // ...
}
private static SnippingTool instance;
public static SnippingTool GetInstance(Bitmap screenShot)
{
        if (instance == null || instance.IsDisposed)
        {
           instance = new SnippingTool(); 
        }
        instance.SetBitmap(screenShot); // if you need otherwise pass it to constructor
        return instance;
}

最新更新