Определение перечислений вне тела класса, но внутри пространства имен

Сегодня я столкнулся с некоторым кодом, который выглядит следующим образом.

namespace Foo
{

    public enum Game{ High, Low};
    public enum Switch{On, Off};

    public class Bar()
    {
    // Blah
    }
}

Я не мог понять, какая разница между этим и объявлением перечислений внутри класса. AFAIK, вы все равно можете "переопределить" те перечисления внутри класса.

Ответы

Ответ 1

Перечисления - это типы, как классы. Когда вы объявляете enum внутри класса, это всего лишь вложенный тип. Вложенное перечисление просто скрывает другие перечисления с тем же именем, которые объявлены во внешних областях, но вы все равно можете ссылаться на скрытое перечисление через его полное имя (используя префикс пространства имен в вашем примере).

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

Ответ 2

Если вы поместите перечисления в класс, вам нужно будет указывать имя класса каждый раз, когда вы используете его вне класса, например:

SomeLongClassName x = new SomeLongClassName(SomeLongClassName.Game.High, SomeLongClassName.Switch.On);

вместо:

SomeLongClassName x = new SomeLongClassName(Game.High, Switch.On);

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