Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it bad practice to have state in a static class?

I would like to do something like this:

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.
}

This would allow me to manage the global collection of Foos from anywhere. However, I've been told that static classes should always be stateless--you shouldn't use them to store global data. Global data in general seems to be frowned upon. If I shouldn't use a static class, what is the right way to approach this problem?

Note: I did find a similar question, but the answer given doesn't really apply in my case.

like image 473
Matthew Avatar asked May 02 '10 16:05

Matthew


2 Answers

Who stays that static classes should be stateless? Static means stated.

Just know how static classes work in the CLR:

  • You can't control the time when static constructors are called.
  • Static classes have a separate state for each calling program.

Also be aware of concurrency issues.

As a side note, it amazes me how often people say "Don't use X." It would be like someone walking into your toolshed and pointing to half a dozen tools and saying, "Those tools are bad practice." It doesn't make sense.

like image 141
harpo Avatar answered Oct 25 '22 02:10

harpo


Global data is both powerful and a common source of problem, that's why techniques like dependency injection are used. You can think of it as a normal decoupling problem. Having global data that is referenced directly in a lot of places in your program makes a strong coupling between that global data and all those places.

In your example however you have isolated the access to the data into a class, which controls the exact details of the access of the global data. As some global data is often inevitable, I think that this is a good approach.

You can for example compare to how app.config and web.config are used through the .NET framework. They are accessed through a static class System.Configuration.ConfigurationManager with a static property AppSettings, which hides a away the details of how to reach the global data.

like image 27
Anders Abel Avatar answered Oct 25 '22 02:10

Anders Abel