operator for enums

2019-06-13 17:42发布

Just out of curiosity, asking this

Like the expression one below

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

why can't we have an operator for enums?
say,

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

instead of switch statements (even though refactoring is possible)


enum Fruit
{
    apple,
    mango,
    orange      
};

Fruit f = Fruit.apple;

Or is it some kind of useless operator?

5条回答
叼着烟拽天下
2楼-- · 2019-06-13 18:16

Offhand I can think of three reasons:

  1. It's brittle. If somebody decides to reorder the enum, then you'll end up with the wrong functions being called.
  2. It's non-obvious. I can't understand which function will run in which case without switching over to the enum definition and checking which order the enums are in.
  3. Every feature starts with minus 100 points. Something like this is unlikely to justify the effort required to spec, build, document and test it, especially when compared to other features, and especially especially when there's a highly viable alternative already in the language.
查看更多
成全新的幸福
3楼-- · 2019-06-13 18:26

condition is evaluated to true or false. What is proposed algorithm of your non-existing operator? It is difficult to say whether it may be useful or not, but switch-case can do what you need.

查看更多
smile是对你的礼貌
4楼-- · 2019-06-13 18:30

C# borrows syntax from C++, and C++ borrows syntax from C, and C didn't have a ???::: operator, because K&R probably didn't feel like it was necessary. It's not a "useless operator", but it would be considered syntactic sugar.

Moreover, it's not a good idea for an operator to rely on the particular ordering of constants in the enum declaration.

查看更多
Rolldiameter
5楼-- · 2019-06-13 18:31

The main problem - apart from it being unsafe, unnecessary, and probably unreadable in most real cases - is that it promotes a programming model that most people would these days regard as bad.

Most languages have programming/design styles they allow and those they want to promote. C# allows imperative and procedural programming but promotes the use of object oriented techniques. Your operator belongs firmly in the first camp and is not something that the designers of the language would want to support.

If you did want to program in that style then you could use:

    myValue = (f == Fruit.apple) ? fnApple() 
            : (f == Fruit.mango) ? fnMango()
            : fnOrange();
查看更多
欢心
6楼-- · 2019-06-13 18:39

I can't say I've ever wanted such an operator - which would be incredibly brittle by relying on the ordering of the enum values. You can easily use a switch:

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

Alternatively, create a map:

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

myValue = FruitFunctions[f]();

I've used both techniques in various situations, and far prefer them to the suggested operator, I'm afraid.

查看更多
登录 后发表回答