2016-06-22 18 views
8

Qualche suggerimento su come rendere la query sottostante più "leggibile"?Operatore ternario difficile da leggere

var result = result 
       .OrderBy(a => 
        (conditionA) ? 
        valueA : 
        (conditionB ? valueB : 
        (conditionC ? 
        (conditionD ? 
        valueC : valueD) : 
        valueE))); 

È difficile da leggere con il lungo codice di condizione e valore.

+0

Aggiungere la rientranza adeguata e allineare il col ons ':' con i relativi segni questino '?' –

+1

[tag: ternario-operatore]: "Un operatore ternario è ** qualsiasi ** operatore che accetta tre argomenti. Per l'operatore condizionale ternario '?' ... ':', usa '[tag: conditional-operator]'. "(My * emphasis *) –

+0

Ancora meglio * rimuovi tutte le condizioni *. Aggiungi' OrderBy' e' In questo caso, le istruzioni sul codice sono semplici, ma se si desidera specificare il campo di ordinamento in modo dinamico, è possibile farlo facilmente in LINQ –

risposta

5

Esistono diversi modi per migliorare la leggibilità del codice.

indentazione

Un modo è quello di rientrare il codice in un modo leggermente diverso, ma questo aiuta solo la leggibilità un po ':

var result = result.OrderBy(a => 
    conditionA ? valueA : 
    conditionB ? valueB : 
    conditionC ? conditionD ? valueC : 
           valueD : 
       valueE); 

se, altrimenti

Si potrebbe trasforma anche questi operatori ternari in una catena più leggibile di if, else.

var result = Result.OrderBy(a => { 
    if (conditionA) 
    { 
     return valueA; 
    } 
    else if (conditionB) 
    { 
     return valueB; 
    } 
    else if (conditionC) 
    { 
     if (conditionD) 
     { 
      return valueC; 
     } 
     else 
     { 
      return valueD; 
     } 
    } 
    else 
    { 
     return valueE; 
    } 
}); 

IComparer <>

Una possibilità sarebbe quella di scrivere una propria implementazione di IComparer<> e passarlo al metodo OrderBy. Non so quale sia il tipo di oggetto o il tipo di chiave nel codice, quindi assumerò le chiavi string.

public class MyClassComparer : IComparer<MyClass> 
{ 
    public int Compare(MyClass x, MyClass y) 
    { 
     string xKey = getKey(x); 
     string yKey = getKey(y); 
     return string.Compare(xKey, yKey); 
    } 

    private string getKey(MyClass item) 
    { 
     if (item.conditionA) 
     { 
      return item.valueA; 
     } 
     else if (item.conditionB) 
     { 
      return item.valueB; 
     } 
     else if (item.conditionC) 
     { 
      if (item.conditionD) 
      { 
       return item.valueC; 
      } 
      else 
      { 
       return item.valueD; 
      } 
     } 
     else 
     { 
      return item.valueE; 
     } 
    } 
} 

metodo di estensione

Un ultima opzione sarebbe quella di spostare il codice per un metodo di estensione:

public static class MyClassExtensions 
{ 
    public static string GetSortingKey(this MyClass item) 
    { 
     if (item.conditionA) 
     { 
      return item.valueA; 
     } 
     else if (item.conditionB) 
     { 
      return item.valueB; 
     } 
     else if (item.conditionC) 
     { 
      if (item.conditionD) 
      { 
       return item.valueC; 
      } 
      else 
      { 
       return item.valueD; 
      } 
     } 
     else 
     { 
      return item.valueE; 
     } 
    } 
} 

Utilizzando l'ultima opzione, la chiamata a OrderBy è semplicemente:

result.OrderBy(a => a.GetSortingKey()) 
+2

Questo è quello che farei anch'io: operatori ternari multipli sono troppo difficili da capire anche quando si conoscono tutte le regole di analisi. –