Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以在C#中使用带有非默认构造函数的单例?_C#_Singleton_Default Constructor - Fatal编程技术网

是否可以在C#中使用带有非默认构造函数的单例?

是否可以在C#中使用带有非默认构造函数的单例?,c#,singleton,default-constructor,C#,Singleton,Default Constructor,我正在为我的一个项目实现一个通知框架。我希望它非常通用,用户可以使用多个传输层,这样他就不需要真正关心使用一种或另一种交付方法(比如说WCF)了。 用户可以访问的接口当然独立于交付方法(WCF或ActiveMQ)。 尽管如此,这两个类(consumer和producer)实现了单例,因此它们实际上使用默认构造函数(也就是说,没有参数)。 我的问题是我想要一个参数,用户想要使用的交付方法。 但据我所知,singleton只使用默认构造函数?这是正常的,因为在参数中使用单例是没有意义的。 那么,我的

我正在为我的一个项目实现一个通知框架。我希望它非常通用,用户可以使用多个传输层,这样他就不需要真正关心使用一种或另一种交付方法(比如说WCF)了。 用户可以访问的接口当然独立于交付方法(WCF或ActiveMQ)。 尽管如此,这两个类(consumer和producer)实现了单例,因此它们实际上使用默认构造函数(也就是说,没有参数)。 我的问题是我想要一个参数,用户想要使用的交付方法。 但据我所知,singleton只使用默认构造函数?这是正常的,因为在参数中使用单例是没有意义的。 那么,我的选择是什么?不是要创建一个单例?是否创建一个方法来设置传递方法

非常感谢您的帮助,
Sebastian

您当然可以将参数与单例一起使用,除了将参数传递到getInstance()方法中,而不是将参数传递到构造函数中。当然,对于真正的单例实现,重写的构造函数必须是私有的。我的示例是用Java编写的,但也适用于C

例如:

Singleton s = Singleton.getInstance(42);
在单例代码中:

private Singleton() {

}

private Singleton(int num) {
   //set num
}

public getInstance(int num) {
  //singleton code (calls the private non-default constructor if an object 
  //does not already exist) 
}

有一些依赖注入框架,比如Spring.Net,可能会对您有所帮助。可以有效地在配置文件中为Singleton构造函数传递参数


我可以建议,如果你有两个不同的行为要求你的单身汉,你可能想子类。这样,您就可以通过调用所需的类行为的单例来获得所需的行为。

使用依赖项注入框架,您可以轻松做到这一点。我在当前的项目中使用了一个类似的构造。所需的只是使用构造函数注入选项,并将该程序集和请求的依赖项的程序集添加到目录中,然后将其正确连接起来

另一种选择是使用某种形式的initialize函数来接受您的选项,并构造singleton实例。您可以在初始化调用期间构造它,而不是在第一次访问时构造它。这里的缺点是,您需要确保在使用singleton之前对其进行初始化(通常在程序启动时使用配置文件)


一个类似但不太容易出错的选项是,只需初始化singleton lazy,并给它一个“default”选项。允许调用者设置一个静态属性来改变构造哪个选项,因此如果它是在构造单例之前设置的,您将得到不同的默认值。不过,这可能会让人困惑,因为您需要再次确保在访问singleton之前设置属性,否则会出现意外行为。

我知道回答最初的问题为时已晚,但我刚刚遇到了这个问题,下面是我解决问题的方法。可能不太理想,但似乎有效。 我创建了一个Init方法,在尝试使用singleton实例之前必须调用该方法

public void Init(/*parameters*/)
{
        if (_isInitialized)
        {
            throw new InvalidOperationException("Component is already initialized!");
        }
        //do your work here
}
对singleton实例的任何其他访问(properties get、set、method调用)都将抛出一个无效的操作异常,告知对象未初始化


我认为这是我所需要的,比GetInstance(params)更容易混淆,因为不存在误解方法功能的风险。缺点是它不会抛出编译时错误,但是没有完成初始化的第一次运行会抛出异常,所以它应该足够好了。

如果在程序生命周期的后期有人调用
Singleton.getInstance(43)?这实际上取决于实现的细节。如果对象只能用一个数字实例化一次,然后再也不能更改,那么该方法将返回创建的原始对象。如果43应该是一个完全不同的对象,那么我的示例中的Singleton类可以保存一个包含所有创建的Singleton的数组,并检查该数组。不管哪种方式看起来都很奇怪。它看起来更像是一个工厂而不是一个单件。当然,我应该指出,这并不是单件的最佳用途。Singleton应该只用于无状态对象,您只需要一个。为什么说Singleton应该是无状态的?单例不就是一个全局(有状态)变量吗?例如,单例可以用于保存某事物的所有当前实例的列表。