operador para enums
-
20-09-2019 - |
Pergunta
Só por curiosidade, perguntando isso
Como a expressão um abaixo
a = (condition) ? x : y; // two outputs
Por que não podemos ter um operador para enums?
dizer,
myValue = f ??? fnApple() : fnMango() : fnOrange(); // no. of outputs specified in the enum definition
em vez de declarações de interruptor (mesmo que a refatoração seja possível)
enum Fruit
{
apple,
mango,
orange
};
Fruit f = Fruit.apple;
Ou é algum tipo de operadora inútil?
Solução
Não posso dizer que nunca quis esse operador - o que seria incrivelmente quebradiço, confiando na ordem dos valores da enumeração. Você pode usar facilmente um 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");
}
Como alternativa, crie um mapa:
static readonly Dictionary<Fruit, Func<Foo>> FruitFunctions =
new Dictionary<Fruit, Func<Foo>> {
{ Fruit.Apple, fnApple },
{ Fruit.Mango, fnMango },
{ Fruit.Orange, fnOrange }
};
...
myValue = FruitFunctions[f]();
Eu usei as duas técnicas em várias situações e as prefiro muito ao operador sugerido, receio.
Outras dicas
Opfeta, posso pensar em três razões:
- É quebradiço. Se alguém decidir reordenar a enumeração, você acabará com as funções erradas sendo chamadas.
- Não é óbvio. Não consigo entender qual função será executada nesse caso sem alternar para a definição de enum e verificar em que ordem as enumes estão.
- Cada recurso começa com menos 100 pontos. É improvável que algo assim justifique o esforço necessário para especificar, construir, documentar e testá -lo, especialmente quando comparado a outros recursos e especialmente especialmente Quando já existe uma alternativa altamente viável no idioma.
C# empréstimos sintaxe de C ++ e C ++ em tomados de sintaxe de C, e C não tinha um ???:::
O operador, porque a K&R provavelmente não parecia necessária. Não é um "operador inútil", mas seria considerado açúcar sintático.
Além disso, não é uma boa idéia para um operador confiar na ordem específica de constantes na declaração de enumeração.
A condição é avaliada como verdadeira ou falsa. O que é o algoritmo proposto do seu operador inexistente? É difícil dizer se pode ser útil ou não, mas o caso do switch pode fazer o que você precisa.
O principal problema - além de ser inseguro, desnecessário e provavelmente ilegível na maioria dos casos reais - é que ele promove um modelo de programação que a maioria das pessoas teria hoje em dia como ruim.
A maioria dos idiomas possui estilos de programação/design que eles permitem e aqueles que desejam promover. C# permite programação imperativa e processual, mas promove o uso de técnicas orientadas a objetos. Seu operador pertence firmemente no primeiro acampamento e não é algo que os designers do idioma gostariam de apoiar.
Se você desejou programar nesse estilo, poderá usar:
myValue = (f == Fruit.apple) ? fnApple()
: (f == Fruit.mango) ? fnMango()
: fnOrange();