views:

664

answers:

8

So I was looking at some code that was checked in and I got all puzzled over:

// Amount of days before cancellation can't be done
enum Cancellation { Limit = 2 };

Asking the guy who checked it in he argued that it's much better to use enums instead of static variables, bettern than this:

private static int CANCELLATION_LIMIT = 2;

So we started arguing. My argument was that he was using enum as a way to store values (it'll break if there were two enum symbols with the same value). He argued it was an antipattern to have static variables in a class.

My question is what best practice should be used for either?

A: 

I think that you should use enums if you have a set of values directly connected.

Something like: enum Status { Open = 1, Closed =2, Waiting=3 };

For everything else, I'd say static variables are the way to go.

Sergio
A: 

I don't know that it is an anti-pattern to have static variables in a class (?). For example, the Color class in the .Net framework has lots of static public variables, such as Color.Red. So, from that perspective, I would agree with you.

However, there may be a compromise: use private const CANCELLATION_LIMIT = 2; and both of your should be happy. For him, there will be no global variable for the class (?), as the consts will be replaced by the compiler, and you will get a single point of change with a clear name.

Travis
+11  A: 

return "Is it logically a set of values" ? "Enum is appropriate" : "Static const is fine"

(I'm a big fan of the logically consistent)

annakata
Absolutely agree, 100%.
Ray Hidayat
in C# I don't think you can have a static const. its either const, or static readonly :)
Svish
in fact all consts are implicitly static, and explicit specification is prohibited (I'd be fine with a static readonly though)
annakata
+8  A: 

Enums are typed.

That is, if you have a method where you have to pass a certain 'state' to a method for instance, you can only pass 'valid' arguments. For instance:

enum OrderState 
{
  pending = 1,
  shipped = 2
}

public IList<Order> GetOrdersInState( OrderState )
{
}

This is a good example -imho- of using enums. When OrderState is an int for which you create 2 const ints, you have no restriction and are able to pass invalid values. The compiler won't complain.

However, the case that you're bringing up, I think using enums is not a valid solution. It's a misuse of using an int, and a const int should be used.

Enums are good, but they should be used where they must be used. They're not the preferred tool in every situation. Having a const or static var is in this case not an antipattern.

Frederik Gheysels
And refactoring is not as easy with enums, for instance if you choose to make the static an instance method due a requirement for this cancellation limit to be dependent on a DB entry...
vanslly
+1  A: 

No, How do you define static string variables or decimal values in enum?

lakshmanaraj
A: 

I don't think that CANELLATION_LIMIT sounds like an enum, which is usually a set of choices.

For something different, if it was a const, then maybe... but currently it is a mutable field?

Note that enums are limited to integer-based types, so it can't be used for float, string, etc.

Marc Gravell
(this has a downvote... I'd love to know why...)
Marc Gravell
+1  A: 

For immutable values intended to be unique, enumerations are the way to go. The question to ask is simple: should the object store the value itself, even statically? In many cases, such as when describing errors or action, the answer is no. Remember, enums was born as a replacement for #define: it associates typical values with identifiers and it provides a type, it doesn't actually say "store this constant here".

I presume you don't actually want to store anything, but provide such typical values. static const members are only useful when you intend to use them as such, for example if you need to pass them by reference to a method.

Eduard - Gabriel Munteanu
const also gives names for those magic numbers in order to make more descriptive code, not just for reuse."need to pass them by reference to a method". No, constant primitives like are passed by value, not reference.
vanslly
"static const variables" - isn't that an oxymoron?
Marc Gravell
You can pass a const by reference or by address very well. Something as in: pass_me_an_object_by_addr(
Eduard - Gabriel Munteanu
' "static const variables" - isn't that an oxymoron? ' - yes, changed to a better term.
Eduard - Gabriel Munteanu
@Eduard: I was really talking within the context of managed C#
vanslly
A: 

Is there a performance difference when using enum or static variables?

newbie