-->

What's the difference between enums & using st

2019-05-17 07:44发布

问题:

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

回答1:

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.



回答2:

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)


回答3:

Well, for one, type safety, at least, type safety that is not as easily circumvented. For example, using an enumerated value I can create a function prototype such as

void Foo( SomeEnum value );

Whereas with your static class I would have to take an int parameter. Sure, you can cast away the type safety, but it's easier to use and makes it more obvious, and you can also perform conversions more easily. Also, enum's give auto incremented values, pretty-print support in the debugger, binding benefits with controls like a property grid. You get the idea.