В чем разница между перечислениями и использованием статических классов с константами? - PullRequest
3 голосов
/ 06 апреля 2011

Каковы значения производительности между этими двумя элементами? Я недавно видел статический класс в дикой природе, и я не уверен, что с ним делать.

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

Ответы [ 3 ]

15 голосов
/ 06 апреля 2011

Разница в типе безопасности. Предположим, у вас есть два из этих перечислений. Как вы собираетесь отличить:

void SomeMethod(int x, int y)

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

против

void SomeMethod(SomeEnum x, SomeOtherEnum y)

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

Таким образом, везде у вас есть выражение, которое хочет быть одним из определенного набора значений, вы можете прояснить для читателя и компилятор, какой набор значений вы Вы заинтересованы в том, если вы используете перечисления. Только с целыми ... не так много.

4 голосов
/ 06 апреля 2011

Перечисления встроены непосредственно в IL, в то время как поля (например, те, что есть в вашем классе) потребуют инструкции по загрузке поля, которая может быть немного дороже.Вот код IL для вызова метода, который принимает перечисление против полей.

 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)
2 голосов
/ 06 апреля 2011

Ну, во-первых, безопасность типов, по крайней мере, безопасность типов, которые не так легко обойти. Например, используя перечисляемое значение, я могу создать прототип функции, такой как

void Foo (значение SomeEnum);

В то время как с вашим статическим классом мне пришлось бы принимать параметр int. Конечно, вы можете отказаться от безопасности типов, но она проще в использовании и делает ее более очевидной, а также вы можете легче выполнять преобразования. Кроме того, перечисления дают автоматически увеличиваемые значения, симпатичную поддержку печати в отладчике, связывают преимущества с элементами управления, такими как сетка свойств. Вы поняли.

...