Domanda

Solo per curiosità, chiedo questo

Come l'espressione qui sotto

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

perché non possiamo avere un operatore per le enumerazioni?
Dire,

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

invece delle istruzioni switch (anche se il refactoring è possibile)


enum Fruit
{
    apple,
    mango,
    orange      
};

Fruit f = Fruit.apple;

O è una specie di operatore inutile?

È stato utile?

Soluzione

Non posso dire di aver mai desiderato un operatore del genere, che sarebbe incredibilmente fragile facendo affidamento sull'ordinamento dei valori enum.Puoi facilmente utilizzare un interruttore:

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

In alternativa, crea una mappa:

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

myValue = FruitFunctions[f]();

Ho usato entrambe le tecniche in varie situazioni e, temo, le preferisco di gran lunga all'operatore suggerito.

Altri suggerimenti

A prima vista posso pensare a tre ragioni:

  1. È fragile.Se qualcuno decide di riordinare l'enumerazione, ti ritroverai con la chiamata delle funzioni sbagliate.
  2. Non è ovvio.Non riesco a capire quale funzione verrà eseguita in tal caso senza passare alla definizione dell'enumerazione e verificare in quale ordine si trovano le enumerazioni.
  3. Ogni funzionalità inizia con meno 100 punti. È improbabile che qualcosa del genere giustifichi lo sforzo richiesto per specificarlo, costruirlo, documentarlo e testarlo, soprattutto se confrontato con altre funzionalità, e soprattutto soprattutto quando esiste già un'alternativa altamente valida nella lingua.

C# prende in prestito la sintassi da C++ e C++ prende in prestito la sintassi da C e C non aveva un ???::: operatore, perché K&R probabilmente non lo riteneva necessario.Non è un "operatore inutile", ma sarebbe considerato zucchero sintattico.

Inoltre, non è una buona idea per un operatore fare affidamento sul particolare ordine delle costanti nella dichiarazione enum.

la condizione viene valutata come vera o falsa.Qual è l'algoritmo proposto dal tuo operatore inesistente?È difficile dire se possa essere utile o meno, ma switch-case può fare ciò di cui hai bisogno.

Il problema principale - a parte il fatto che è pericoloso, non necessario e probabilmente illeggibile nella maggior parte dei casi reali - è che promuove un modello di programmazione che la maggior parte delle persone oggigiorno considererebbe pessimo.

La maggior parte dei linguaggi ha stili di programmazione/progettazione che consente e quelli che desidera promuovere.C# consente la programmazione imperativa e procedurale ma promuove l'uso di tecniche orientate agli oggetti.Il tuo operatore appartiene saldamente al primo campo e non è qualcosa che i progettisti del linguaggio vorrebbero supportare.

Se volessi programmare in quello stile allora potresti usare:

    myValue = (f == Fruit.apple) ? fnApple() 
            : (f == Fruit.mango) ? fnMango()
            : fnOrange();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top