оператор для перечислений - PullRequest
0 голосов
/ 17 марта 2010

Просто из любопытства спрашиваю это

Как и выражение, приведенное ниже

a = (condition) ? x : y; // two outputs

почему у нас не может быть оператора для перечислений?
скажем,

myValue = f ??? fnApple() : fnMango() : fnOrange(); // no. of outputs specified in the enum definition

вместо операторов switch (даже если возможен рефакторинг)


enum Fruit
{
    apple,
    mango,
    orange      
};

Fruit f = Fruit.apple;

Или это какой-то бесполезный оператор?

Ответы [ 5 ]

17 голосов
/ 17 марта 2010

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

switch (f)
{
    case Fruit.Apple: myValue = fnApple(); break;
    case Fruit.Mango: myValue = fnMango(); break;
    case Fruit.Orange: myValue = fnOrange(); break;
    default: throw new ArgumentOutOfRangeException("f");
}

Либо создайте карту:

static readonly Dictionary<Fruit, Func<Foo>> FruitFunctions = 
    new Dictionary<Fruit, Func<Foo>> {
    { Fruit.Apple, fnApple },
    { Fruit.Mango, fnMango },
    { Fruit.Orange, fnOrange }
};
...

myValue = FruitFunctions[f]();

Я использовал оба метода в различных ситуациях и, боюсь, предпочитаю их предложенному оператору.

4 голосов
/ 17 марта 2010

Случайно я могу думать о трех причинах:

  1. Это хрупко.Если кто-то решит переупорядочить перечисление, то вы получите неправильные вызовы функций.
  2. Это неочевидно.Я не могу понять, какая функция в каком случае будет работать, не переключаясь на определение перечисления и не проверяя, в каком порядке находятся перечисления.
  3. Каждая функция начинается с минус 100 баллов. Что-то вродеэто вряд ли оправдывает усилия, необходимые для его спецификации, сборки, документирования и тестирования, особенно по сравнению с другими функциями, и , особенно особенно , когда в языке уже существует весьма жизнеспособная альтернатива.
2 голосов
/ 17 марта 2010

C # заимствует синтаксис у C ++, а C ++ заимствует синтаксис у C, и у C не было оператора ???:::, потому что K & R, вероятно, не чувствовал, что это необходимо. Это не «бесполезный оператор», но это будет считаться синтаксическим сахаром.

Более того, для оператора не стоит полагаться на определенный порядок констант в объявлении enum.

0 голосов
/ 17 марта 2010

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

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

Если вы хотите программировать в этом стиле, вы можете использовать:

    myValue = (f == Fruit.apple) ? fnApple() 
            : (f == Fruit.mango) ? fnMango()
            : fnOrange();
0 голосов
/ 17 марта 2010

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

...