代码之家  ›  专栏  ›  技术社区  ›  Matthew

在静态类中有状态是一种不好的做法吗?

  •  9
  • Matthew  · 技术社区  · 16 年前

    我想这样做:

    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 ,但给出的答案并不适用于我的情况。

    7 回复  |  直到 9 年前
        1
  •  10
  •   harpo Binary Worrier    16 年前

    谁认为静态类应该是无状态的?静态 方法

    只需了解静态类在CLR中的工作方式:

    • 不能控制调用静态构造函数的时间。
    • 静态类对于每个调用程序都有一个单独的状态。

    作为旁注,我很惊讶人们经常说“不要使用X”。就像有人走进你的工具棚,指着六个工具说,“那些工具是坏习惯。”这是没有意义的。

        2
  •  4
  •   Anders Abel    16 年前

    然而,在您的示例中,您将对数据的访问隔离到一个类中,该类控制全局数据访问的确切细节。由于一些全球数据往往不可避免,我认为这是一个好办法。

    System.Configuration.ConfigurationManager AppSettings ,这隐藏了如何访问全局数据的细节。

        3
  •  3
  •   Jordan T. Cox    16 年前

    您在这里寻找的似乎是一个单例类,而不是一个静态类。对于无状态例程,应该引用静态类和方法。一个单例类在每个应用程序运行时实例化一次,而且只实例化一次,并且具有类本身的全部功能。以后每次引用它时,都会返回具有完全相同成员属性的完全相同的实例。

    http://www.yoda.arachsys.com/csharp/singleton.html

        4
  •  3
  •   DHN    16 年前

    一般来说还不错。在一些罕见的情况下,这样做比用大量开销实现其他东西更为必要。

    但建议注意安全。

    您应该锁定对字典的每个调用,以便一次只有一个线程可以访问它。

    
    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;
            }
        }
    
    
        5
  •  0
  •   Brettski    16 年前

        6
  •  0
  •   Ray    16 年前

    我总是在静态类中使用列表来处理那些永远不会(或者很少)改变的事情——方便地加载挑选列表之类的东西,而不会每次都碰到数据库。因为我不允许更改,所以我不必担心锁定/访问控制。

        7
  •  0
  •   George Handlin    16 年前

    另一件需要考虑的事情是应用程序本身和它的预算。真的需要比静态类更复杂的东西吗?

    推荐文章