我想做这样的事情:
public class Foo {
// Probably really a Guid, but I'm using a string here for simplicity's sake.
string Id { get; set; }
int Data { get; set; }
public Foo (int data) {
...
}
...
}
public static class FooManager {
Dictionary<string, Foo> foos = new Dictionary<string, Foo> ();
public static Foo Get (string id) {
return foos [id];
}
public static Foo Add (int data) {
Foo foo = new Foo (data);
foos.Add (foo.Id, foo);
return foo;
}
public static bool Remove (string id) {
return foos.Remove (id);
}
...
// Other members, perhaps events for when Foos are added or removed, etc.
}
这将允许我从任何地方管理Foo
的全局集合。但是,我被告知静态类应该始终是无状态的 - 您不应该使用它们来存储全局数据。总的来说,全球数据似乎不受欢迎。如果我不应该使用静态类,那么解决这个问题的正确方法是什么?
注意:我确实找到了similar question,但给出的答案并不适用于我的情况。
答案 0 :(得分:9)
谁坚持静态课程应该是无国籍的?静态表示陈述。
只知道静态类在CLR中的工作原理:
还要注意并发问题。
作为旁注,令人惊讶的是人们常说“不要使用X”。就像有人走进你的工具并指着六个工具说:“这些工具是不好的做法。”这没有意义。
答案 1 :(得分:4)
全局数据既强大又是问题的常见来源,这就是使用依赖注入等技术的原因。您可以将其视为正常的解耦问题。拥有在程序中很多地方直接引用的全局数据,可以在全局数据和所有这些地方之间建立强大的耦合。
在您的示例中,您已将对数据的访问隔离到一个类中,该类控制全局数据访问的确切详细信息。由于一些全球数据往往是不可避免的,我认为这是一个很好的方法。
例如,您可以通过.NET框架比较app.config和web.config的使用方式。它们通过静态类System.Configuration.ConfigurationManager访问,其静态属性AppSettings,隐藏了如何获取全局数据的详细信息。
答案 2 :(得分:3)
你在这里寻找的是一个单例类,而不是一个静态类。应该为无状态例程引用静态类和方法。单例类实例化一次,每个应用程序运行一次,并且具有类的全部功能。每次您将来引用它时,您将获得具有完全相同成员属性的完全相同的实例。
“C#singleton”的第一个google结果似乎对实现有相当不错的解释。 http://www.yoda.arachsys.com/csharp/singleton.html
答案 3 :(得分:2)
一般情况下都不好。在一些罕见的情况下,这样做是必要的,而不是实现其他开销很大的东西。
但建议注意线程安全。
您应该锁定对字典的每次调用,以便一次只能有一个线程访问它。
private static readonly object LockStaticFields = new object();
public static Foo Add (int data) {
lock(LockStaticFields)
{
Foo foo = new Foo (data);
foos.Add (foo.Id, foo);
return foo;
}
}
答案 4 :(得分:0)
在类中使用只读静态属性,该属性在类的所有实例中都是相同的。根据需要从构造函数等增加和减少
答案 5 :(得分:0)
我一直在静态类中使用列表来处理永远(或极少)更改的内容 - 这对于加载选择列表很方便,而且每次都不会点击数据库。由于我不允许更改,因此我不必担心锁定/访问控制。
答案 6 :(得分:0)
需要考虑的另一件事是应用程序本身及其预算。是否真的需要比静态类更复杂的东西?