Q:

What's the difference between enums & using static classes with constants?

What are the performance implications between these two items? I've seen the static class in the wild recently and I'm not sure what to make of it.
public enum SomeEnum
{
   One = 1,
   Two,
   Three
}

public static class SomeClass
{
   public static readonly int One = 1;
   public static readonly int Two = 2;
   public static readonly int Three = 3;
}

A:

The difference is type safety. Suppose you have two of these enums. How are you going to tell the difference:
void SomeMethod(int x, int y)

// Compiles, but won't do what you want.
SomeMethod(SomeOtherClass.Xyz, SomeClass.One);

vs
void SomeMethod(SomeEnum x, SomeOtherEnum y)

// Compile-time error
SomeMethod(SomeOtherEnum.Xyz, SomeEnum.One)

So everywhere you have an expression which wants to be one of a particular set of values, you can make it clear to both the reader and the compiler which set of values you're interested in if you use enums. With just ints... not so much.

A:

Enums are embedded directly in IL whereas fields (like the ones you have in your class) will need a field load instruction which may be slightly more expensive. Here is the IL code for calling a method that accepts an enum versus fields.
 IL_0001:  ldc.i4.1
  IL_0002:  call       void ConsoleApplication2.Program::TestMethod(valuetype ConsoleApplication2.SomeEnum)
  IL_0007:  nop
  IL_0008:  ldc.i4.3
  IL_0009:  call       void ConsoleApplication2.Program::TestMethod(valuetype ConsoleApplication2.SomeEnum)
  IL_000e:  nop
  IL_000f:  ldsfld     int32 ConsoleApplication2.SomeClass::Two
  IL_0014:  call       void ConsoleApplication2.Program::TestMethod(int32)
  IL_0019:  nop
  IL_001a:  ldsfld     int32 ConsoleApplication2.SomeClass::One
  IL_001f:  call       void ConsoleApplication2.Program::TestMethod(int32)

