I would take it a step further, and bring it to 3 cases. Although there are variations on each, this is the rules I use the majority of the time when C# programming.
In case 2&3, always go to the Property Accessor (not the field variable). And in case 1, you are saved from even having to make this choice.
1.) Immutable property (passed in to constructor, or created at construction time). In this case, I use a field variable, with a read-only property. I choose this over a private setter, since a private setter does not guarantee immutability.
public class Abc
{
private readonly int foo;
public Abc(int fooToUse){
foo = fooToUse;
}
public int Foo { get{ return foo; } }
}
2.) POCO variable. A simple variable that can get/set at any public/private scope. In this case I would just use an automatic property.
public class Abc
{
public int Foo {get; set;}
}
3.) ViewModel binding properties. For classes that support INotifyPropertyChanged, I think you need a private, backing field variable.
public class Abc : INotifyPropertyChanged
{
private int foo;
public int Foo
{
get { return foo; }
set { foo = value; OnPropertyChanged("foo"); }
}
}
I think you've almost answered your own question there.
The second piece of code is preferred over the first because it offers type-safety. With the first piece, if you have a similar enumeration of Fish then you can say something like
MostNotableGrievance grievance = Fish.Haddock;
and the compiler won't care. If Fish.Haddock = 2 then the above will be exactly equivalent to
MostNotableGrievance grievance = MostNotableGrievance.FlipFlopping;
but obviously not instantly readable as such.
The reason enumerations are often no better is because the implicit conversion to and from int leave you with the exact same problem.
But, in C#, there is no such implicit conversion, so an enum is a better structure to use. You'll rarely see either of the first two approaches used.
Best Answer
Adding to Eldritch Conundrum's answer (since he has not updated it):
In many cases you might indeed be able to replace Enums
by simple constants or static classes with public constants, but there is more to Enums than meets the eye.
Intellisense (= auto completion in VS, MonoDevelop, etc...) provides support for enums, it does not do so for constants.
You should use enums to enforce strong typing on parameters, properties and return values that represent a set of values. The set of values should be closed, not subject to constant change.
You can extend enums:
Taken from: http://damieng.com/blog/2012/10/29/8-things-you-probably-didnt-know-about-csharp
And of course Enums are usefull for Bitwise comparisons with the [Flags] attribute and in recent versions of .NET they have a .HasFlag method.
Not really an answer, just some extra info.