Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.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# - Fatal编程技术网

C# 单例还是静态-我应该使用什么?

C# 单例还是静态-我应该使用什么?,c#,C#,我不知道该用什么。我有三节课密码服务,设置服务,文件服务。这些类每个包含大约2个方法。这些方法正在更多的程序集中使用。现在我把它当作一个单身汉。但我不确定我是否应该。我认为一个静态类就足够了。 你觉得怎么样 代码: public class PasswordService { private PasswordService(){} private static PasswordService _instance; public static PasswordServ

我不知道该用什么。我有三节课<代码>密码服务,
设置服务
文件服务
。这些类每个包含大约2个方法。这些方法正在更多的程序集中使用。现在我把它当作一个单身汉。但我不确定我是否应该。我认为一个静态类就足够了。 你觉得怎么样

代码:

public class PasswordService
{

    private PasswordService(){}

    private static PasswordService _instance;

    public static PasswordService Instance
    {
        get { return _instance ?? (_instance = new PasswordService()); }
    }

    public byte[] EncryptPassword(string password)
    {

        var protectedPass = Encoding.UTF8.GetBytes(password);
        return ProtectedData.Protect(protectedPass, null);
    }

    public string DecryptPassword(byte[] encryptedPassword)
    {
        var unprotectedPass = ProtectedData.Unprotect(encryptedPassword, null);
        return Encoding.UTF8.GetString(unprotectedPass, 0, unprotectedPass.Length);
    }
}

1-为这些服务创建一个单例是正确的,因为它们似乎要处理一个特定的任务


2-尽可能避免静态,因为如果您使用TDD并使用Contineus Integration server进行自动单元测试,您将无法有效地模拟静态。

1-为这些服务创建单例是正确的,因为这些服务似乎要处理一个特定的任务


2-尽可能避免静态,因为如果使用TDD并使用Contineus Integration server进行自动单元测试,则无法有效地模拟静态。我建议您保留单例,除非您使用的是实例或DI。单例可以很容易地重构为实例,而静态类必须重新实现为非静态类。此外,您可以用测试假人替换实例,而替换静态实现几乎是不可能的

例如,您可能会遇到这样一种情况:对于两个不同的配置文件,您的程序必须处理多个
FileConfiguration
实例。可以将单个实例拆分为两个实例池

我遇到这个问题时使用了一个DAO类,该类过去是静态的,能够连接到一个DB。我们必须重构它,因为新的需求包括在一个程序实例中支持n>1个数据库


正如Mikhail指出的,只对真正无状态的东西使用静态。静态字段中的配置文件或所选密码散列算法已经是一种状态,上面示例中的连接字符串也是-即使它们在运行时可能永远不会更改。

我建议您保留单例,除非您使用的是实例或DI。单例可以很容易地重构为实例,而静态类必须重新实现为非静态类。此外,您可以用测试假人替换实例,而替换静态实现几乎是不可能的

例如,您可能会遇到这样一种情况:对于两个不同的配置文件,您的程序必须处理多个
FileConfiguration
实例。可以将单个实例拆分为两个实例池

我遇到这个问题时使用了一个DAO类,该类过去是静态的,能够连接到一个DB。我们必须重构它,因为新的需求包括在一个程序实例中支持n>1个数据库


正如Mikhail指出的,只对真正无状态的东西使用静态。静态字段中的配置文件或所选密码散列算法已经是一种状态,上面示例中的连接字符串也是-即使它们在运行时可能永远不会更改。

您的类中没有任何状态,所以我看不出有任何理由使用类的实例。
我建议您使用静态类。

您的类中没有任何状态,所以我看不出有任何理由使用类的实例。
我建议您使用静态类。

这个问题的答案总是一样的:这取决于情况。我想说的是,单例几乎总是邪恶的。使用每个服务的一个实例。你最终会得到一个更灵活的设计,在那里你可以看到你真正的依赖关系。@SoMoS:你本质上是说“单身是邪恶的,所以使用他们”。或者你想说“在你想使用这些服务的任何地方创建一个新实例”@Nuffin:对不起,我的意思当然是“在你需要的任何地方创建一个新实例”。如果多个对象必须共享同一个实例,则将其作为参数传递给构造函数,或以最适合设计的方式传递。这个问题的答案总是一样的:这取决于。可能的重复我会说,单例几乎总是邪恶的。使用每个服务的一个实例。你最终会得到一个更灵活的设计,在那里你可以看到你真正的依赖关系。@SoMoS:你本质上是说“单身是邪恶的,所以使用他们”。或者你想说“在你想使用这些服务的任何地方创建一个新实例”@Nuffin:对不起,我的意思当然是“在你需要的任何地方创建一个新实例”。如果多个对象必须共享同一个实例,则将其作为构造函数上的参数传递,或者以最适合设计的方式传递。因此,它可以是单例,或者我应该将其重新创建为静态?因此,它可以是单例,或者我应该将其重新创建为静态?这些类中没有一个保持任何状态。中只有方法。这些类中没有一个保持任何状态。只有方法在里面。但我不认为,我保持任何状态。这些方法只返回结果。这些类没有任何字段。@JurajP至于
密码服务
你是对的,从技术上讲没有状态。但是,例如
EncryptPassword
DecryptPassword
是相互关联的,因为它们共享
编码.UTF8
的使用。在这里以及您的其他服务中,这可能会变成一种类似于
readonly Encoding enc=Encoding.UTF8
的状态,以便进行更简单、更不容易出错的重构。我承认这听起来很牵强,但我很后悔我过去做的一些静态方法,它们不是无状态的,在技术上彼此无关。希望我能很好地表达我的观点……:)但我不认为我保持了任何状态。这些方法只返回结果。这些类没有任何字段。@JurajP至于
密码服务
你是对的,从技术上讲没有状态。但是,例如
EncryptPassword
DecryptPassword
是相互关联的,因为它们共享
编码.UTF8
的使用。在这里和您的其他服务中,这可能会变成一种类似于代码的状态