C# 在这种特定情况下,我应该使用静态类还是实例类?

C# 在这种特定情况下,我应该使用静态类还是实例类?,c#,scope,state,static-classes,C#,Scope,State,Static Classes,我读过关于何时使用静态类以及何时建议使用实例类的帖子。然而,我的印象是,我下面的例子介于两者之间: 不需要类实例,存储状态在AppDomain中的成员之间共享 状态应该可以从AppDomain中的不同类实例访问 不需要抽象或重写 所以,我的问题是:我应该继续使用它作为静态还是使用单例概念更好 public static class SubscriptionManager { private static Dictionary<string, string> Reposit

我读过关于何时使用静态类以及何时建议使用实例类的帖子。然而,我的印象是,我下面的例子介于两者之间:

  • 不需要类实例,存储状态在AppDomain中的成员之间共享
  • 状态应该可以从AppDomain中的不同类实例访问
  • 不需要抽象或重写
所以,我的问题是:我应该继续使用它作为静态还是使用单例概念更好

public static class SubscriptionManager
{
    private static Dictionary<string, string> Repository { get; set; }

    static SubscriptionManager()
    {
        Repository = new Dictionary<string, string>();
    }

    public static void Subscribe(string key, string value)
    {
        if (Repository.ContainsKey(key))
            Repository[key] = value;
        else
            Repository.Add(key, value);
    }

    public static void Unsubscribe(string key, string value)
    {
        if (Repository.ContainsKey(key))
            Repository.Remove(key);
    }

    public static string GetSubscription(string key)
    {
        if (Repository.ContainsKey(key))
            return Repository[key];
        else
            return "";
    }
}
公共静态类订阅管理器
{
专用静态词典存储库{get;set;}
静态订阅管理器()
{
Repository=newdictionary();
}
公共静态无效订阅(字符串键、字符串值)
{
if(Repository.ContainsKey(键))
存储库[键]=值;
其他的
添加(键、值);
}
公共静态无效取消订阅(字符串键、字符串值)
{
if(Repository.ContainsKey(键))
删除(键);
}
公共静态字符串GetSubscription(字符串键)
{
if(Repository.ContainsKey(键))
返回存储库[key];
其他的
返回“”;
}
}

记住,大型静态类可能会占用大量内存,因此在不必要时避免使用它们。
在这种情况下,我建议您使用静态类。这样更好。

您的示例提供了一个类似于存储库的模式的显式实现,如果它是可扩展的,最终可能会证明它更有价值。如果您将其实现为一个静态类,那么您现在就决定这不可能

另一个可能有价值的实现示例可能是使用.NET 4
ConcurrencyDictionary
,这样代码就可以在更高容量的并发场景中使用,因为
Dictionary
类不是线程安全的

您所建议的是非常雅格尼,这对于有某种计划的大型项目的迭代是很好的,但是除非您知道未来会发生什么,否则为什么要限制已经编写的代码的潜力呢

我可能会从您的类生成一个接口来表示它的基本结构(将实现与契约分离),并利用一个IoC容器让您的类的用户决定在他们的场景中使用什么实现


当然,只有当您的项目相当小或者关心在项目之间共享代码时,这才重要。祝你好运

顺便说一句,您不需要任何
ContainsKey()
检查。对于
GetSubscription()
,使用
TryGetValue()
;在其他地方,请始终调用
Remove()
或setter。如果存储库字典是您想在任何地方使用的数据,我认为这是可以的。@user2675751,是的,静态成员提供的功能反过来依赖于存储的状态,必须由同一AppDomain中的多个不同类实例访问。我基本上觉得我只有两个选择,传递实例和一个静态类。@SLaks,fair points,谢谢。但是你认为它应该是静态的还是实例的呢?我有点不相信“如果它持有状态,那么它必须是实例”必须被普遍应用。谢谢,但是a)我不明白为什么静态类占用的内存(即使是那些持有状态的类)比可以说的部分总和还要多(指几个存储状态的类实例,这些状态的总和与存储在静态类中的状态的总和相同),b)我想听听为什么静态类更可取或不可取的原因。@MattWolf:静态字段的值永远不会被GC'd(除非清除字段)。这是否是一个问题完全取决于您的设计。@SLaks,当然可以,但鉴于其目的是共享状态并使状态可供appDomain中的不同类实例和子类访问,它们也不会是GCd,不是吗?本例中的状态的目的是在应用程序的整个生命周期内共享状态。这是一个仅适用于此项目的解决方案。而且目标定义良好,没有计划扩展性。我目前使用的实例类效率很低,因为无论子类有多深,我都需要将实例传递给每个访问器。(顺便说一句,代码只是描述问题的示例,它并不反映实际状态或功能)