tags:

views:

366

answers:

13

I recently made a recommendation to one of my colleagues stating that on our current project (C#) "services should be stateless and therefore static".

My colleague agreed and indicated that in our project the services are (and should be) indeed stateless. However my colleague disagreed that static implies no state and that stateless should mean static.

My questions is “does a method marked as static imply that it requires no state and that in a majority of cases should stateless methods be made static”.

+7  A: 

Static nearly means global. There is still an instance, and there is still state in that instance, but it is the static instance, which means there is only one and all callers always refer to that one.

Rex M
@Rex, I don't believe it is technically accurate to call the class definition as an "instance" of the class. There is no data structure on the heap for the class itself. Static variables are stored in the class definition itself, which is NOT an "instance" of the class. When you code a singleton, there is one and only one instance created... The class definition, (where static fields are stored, is not another second instance... and when no instance has been "new"'d up for a class, that the class has one or more static variables does not mean it has one "instance"...
Charles Bretana
@Charles I think this is more of a philosophical discussion than where the bytes are stored.
Rex M
@Rex, I guess I could agree with that characterization, but if you mean to imply that it's not an important one, I'd ask politely that you reconsider. The distinction certainly has more consequences that just where the bytes ar stored. Instances can dissappear, (when they are garbage collected), and their instance-level values go with them. Static fields are stored with the class definition, which is NOT an instance and as it never dissappears, has permanent lifetime (until the AppDomain Unloads)
Charles Bretana
You're both right (I learned that in California): it's still an instance, and there's still state in that instance. But the instance is not of Class Foo but rather of Class Class (depending on the language). Or something like that...
Yar
@Charles I don't think it's unfair to characterize it as an instance. A type and all the static members on a type are initialized and stored on the heap when the type is first accessed, and even though they don't get GC'd doesn't necessarily mean anything.
Rex M
@Charles, Unless I read Rex wrong, he's correct, but I think you're reading him differently. I read his "There is still an instance" as referring to the static *variables* within the class. Consider `class A { static String B = "boo"; }` -- here *B* is an instance of String, even if no instance of *A* is ever created.
NVRAM
@NVRAM I really do mean there is a static instance. There is a single instance of the Type which lives for the life of the AppDomain, and all the static members are initialized and stored with it on the heap.
Rex M
If there really weren't an instance of the Type, then there couldn't be a static constructor (`cctor`), which is called when (or before) the first static method or property is invoked and *can be used to initialize static data members* -- MSDN. Ergo: there's a `cctor`, which allocates the "static instance", which, is an *instance of the type*.
Abel
To all: the static constructor is more correctly called an intializer. It does not construct an instance, it initializes the type. And an instance of the 'type' is not an instance of the 'class'. I quote from don Boxes "Essential .Net" Most members of a class can be defined as "per instance" or "per Type" (instance-based or static). "a Per-instance member requires an instance of the type in order to access it. A per-Type member does not have this requirement. In C# thedefault is per-instance. ... change this to per-Type by using the static keyword.
Charles Bretana
When an actual instance is created, a variable is created that holds a reference (address pointer) to an object on the Heap, which contains a pointer (called htype) to another in memory structure called CORINFO_CLASS_STRUCT. This structure is the represeentation of the TYPE, and contains all the definitions for the type and (probably) is where all static fields are stored. Each Type used in your code gets a CORINFO_CLASS_STRUCT, once and once only, sometime prior to the first use of the Type. It is not an 'instance' of the Type, it is a data structure representing the Type.
Charles Bretana
So, to summarize, this CORINFO_CLASS_STRUCT created the first time a Type is used is a representation of the Type , not an instance of the type. This is not just semantics, because CORINFO_CLASS_STRUCT is totally different from, in structure and function, from what is created on the heap as an instance of a type. In fact if you write Type myTyp = typeof(MyClass);, the new object on the heap is of Type 'Type', not 'MyClass', and two CORINFO_CLASS_STRUCTs are created, (if this is first reference o each), one for Type 'Type', and one for Type 'MyClass'.
Charles Bretana
@Rex, If all this discussion is only because you are using the word 'instance' to refer to the CORINFO_CLASS_STRUCT created for each type upon first use of the type, please read up a bit more about this data structure and what it does. It is very different from all other constructed 'instances' of the type. imho, the use of the word 'instance' to refer to this data structure communicates to the average .Net user much that is not true, and therefore, I would advise against this.
Charles Bretana
ANother interesting tidbit here, is that you get a CORINFO_CLASS_STRUCT for each and every Type you reference... So if your code has a class defined as Dog, that inherits from Mammal, that inherits from Animal, that inherits from Object, the first time you use Dog in your code you will get FOUR (4) CORINF_CLASS_STRUCT data structures, one for each type you have referred to - even if the reference was to a static field in Dog. Would you really want to say that you now have 4 instances of Dog?
Charles Bretana
+3  A: 

A static method, in C#, can access the static variables of its containing class, and if it does, it's not stateless. I've seen some painful instances of non-reentrant "stateless" static methods triggering fun race conditions.

A truly stateless method can indeed be made static, and generally should.

Michael Petrotta
+5  A: 

does a method marked as static imply that it requires no state

1) No. You cannot say static methods imply that it requires no state because static methods can access static/singleton resources.

a majority of cases should stateless methods be made static

2) Yes. Methods that require no state, therefore require no instance, should be generally made static.

Ciwee
Mark the "generally". I agree, but too often, when people find out that a particular method does not require state, they change it to `static`. But if the action is related to the stateful object, and if its usage is considered to be done from an instance (i.e., "feel" of the method), the method should not be made static.
Abel
@Abel: the problem is CA will complain if a non-`static` method doesn't use `this`.
Dan
A: 

That is generally correct. However you can have static variables, which allow your static methods to have state. For instance, take this FooBarFactory class:

class FooBarFactory
{
    private static _id = 0;
    public FooBar MakeAFooBar()
    {
        FooBar foo = new FooBar();
        foo.ID = _id;
        _id++;
    }
}
class FooBar
{
    public int ID {get;set;}
}

In that case your static method has a minimum of state, but it's (probably) neccessary.

RCIX
did you perhaps mean to say "it's (probably) unnecessary"?
Abel
No not really...
RCIX
+1  A: 

static can be stateful. you just have to define static containers for said state. and the containers are shared among all calls to your static methods.

Oren Mazor
A: 

If you want a single instance with state, use a singleton pattern; it makes the intent clear that you're working with a single-occurrence object.

From that, I would then treat all static classes and methods as stateless. It just helps keep sanity.

Cylon Cat
+3  A: 

I find it rather scary to say that stateless is the same as static as these are two different worlds. Stateless means that there is no state kept, i.e., a perfect example is an HTTP connection (once data is send, the connection is closed and there's no memory kept), where we are actually trying to do our best to maintain state regardless (login state for one).

Static on the other hand is a term used to describe a way that a method is invoked. In C# that means that a method can be invoked without a class instance, but an instance of a class is not the same as state. There's still the static instance and that's perfectly capable of maintaining state: any static member variable, field or property can maintain state. A static method or class is also perfectly capable of maintaining state by using memory mapped files, a database or whatever. Static is a calling convention, nothing more and is not related to being stateless or not.

Abel
+1  A: 

Every class has a class definition structure, where static fields are represented and stored. Every "instance" of the class has access to the static fields stored in the class definition (a data structure caleld CORINFO_CLASS_STRUCT). Even when NO instances have been created, code anywhere in your assembly can access these static class-level fields by using the syntax classname.StaticFieldName, without any instance at all.

Since the values stored in these static class-level fields are persisted, they are definitely state. In fact, they are state shared by not only any instances of the class that might exist, they are shared throughout the assembly, whether any instances have been created or not.

Even more significant, since once a CORINFO_CLASS_STRUCT class definition has been loaded, unlike a true instance of the class, it is never unloaded until the assembly (or the AppDomain) is unloaded, so it is arguably more stateful than any instance field defined in a class, because an instance field dissapears when the instance gets garbage collected.

For more information check out CORINFO_CLASS_STRUCT link to Don Boxes' great book, Essential .Net

Charles Bretana
+2  A: 

static is a language keyword and state is a design concept. There's an obvious relationship between these two things, but it is a relationship of the concrete to the metaphysical, not a relationship of cause and effect. It is possible for static methods to refernce some kinds of state information.

Regarding stateless methods, here we are talking about method that don't reference a class instance, i.e. a this pointer. Marking these methods as static improves the clarity of the code and is consistent with best practices. Note that in this case we are talking a specific kind of "statelessness" and not making a general commentary about the use of stateful contexts.

Paul Keister
+3  A: 

I think his statement makes about as much sense as "Democracies should use yellow paper ballots".

He is mixing a high level design concepts "stateless services" with a low level technical implementation detail "using static classes".

Stateless services can (and have been) implemented in languages which supports only static variables (e.g. COBOL, RPG) and languages which dont even allow static variables (Erlang etc.).

I could easily imagine a case where stateless service was implemented largly using static classes, becuase they were there and already implemented the correct business logic, although its generally considered good Java programing practice not to use static classes unless you really need to.

He also serioulsy misunderstands what "static" is all about -- a static variable is a way of storing state between invocations -- and would therefore seem a better match with a "stateful" service.

James Anderson
+1  A: 

The short answer to your question is "no", static does not imply "no state".

In reference to your other comments, static can be used to help you implement a stateless service, but static alone is not sufficient. Another tool/technique to help make something stateless is to use immutable data structures. This (currently) isn't one of C#'s fortes, especially when compared to F#.

Dan
A: 

Beyond rehashing all the definitions of "static" that one can run through, the answer is "yes." Static methods may happily modify the state of the Class itself (represented through static variables), and even modify the state of instances of the class (notably, when they get passed an instance or set of instances). However, most of the time, you will use static methods in cases where no state is changed. The most important example is to find or create an instance (factory methods).

That said, the real answer is "no." In real life (Web Services over HTTP, for instance, or interaction with any kind of Orb), services never expose their service methods using actual static methods. You usually call static methods to get an instance of the service (or an instance of the service factory, from which you get an instance!), and then work with that. This is because your service proxy, internally, needs to keep track of where it's at. So while your methods seem stateless to you, they are really not.

Hope this wasn't too confusing :)

Yar
+1  A: 

A Static class is not stateless. It can still have variables which, although static, have a state.

A Static class without any class-level variables is stateless. It holds no data.

Kirk Broadhurst