In C Sharp, come posso impostare un'istruzione if che controlla se una delle diverse condizioni è vera? Deve essere solo una delle condizioni, se zero o due o più sono vere, se dovrebbe essere falso.Se istruzione - 'o' ma 'NON' e '
risposta
si potrebbe scrivere un metodo di supporto. Questo ha il vantaggio di cortocircuiti, solo valutare esattamente come molti come necessario,
public static bool IsExactlyOneTrue(IEnumerable<Func<bool>> conditions) {
bool any = false;
foreach (var condition in conditions) {
bool result = condition();
if (any && result) {
return false;
}
any = any | result;
}
return any;
}
Questo metodo può essere semplificato in 'return! Conditions.Where (cond => cond()). Skip (1) .Any();' È discutibilmente più leggibile e potrebbe rallentare i capelli, ma a meno che questo non sia effettivamente trovato per essere significativo, andrei per il più conciso. –
Per ulteriori informazioni, questo deve essere più simile a questo per funzionare correttamente: 'var trueConditions = conditions.Where (cond => cond()); if (! TrueConditions.Take (1) .Any()) return false; return! TrueConditions.Skip (1) .Any(); 'Sto iniziando ad apprezzare la tua risposta meglio del mio approccio LINQ. –
@TimS .: Ma ciò potrebbe causare la valutazione delle due espressioni leader risultanti da falsi. Non penso che ci sia un modo elegante di farlo in LINQ (eccetto che proiettando indici, che sconfigge l'intero scopo). – Douglas
Andando per semplicità, si può solo tenere un conteggio parziale:
int totalTrue = 0;
if (A) totalTrue++;
if (B) totalTrue++;
if (C) totalTrue++;
...
return (1 == totalTrue);
Personalmente scriverei l'ultima istruzione come 'return totalTrue == 1;'.Capisco la logica per scrivere tali test a ritroso, ma non sono d'accordo con essa - e le parentesi non sono necessarie. –
@KeithThompson, voglio solo mantenere l'abitudine di scrivere il codice nell'ordine in cui torno mai al C++. –
@Adam V: Quando sei a Roma, fai come i romani. C# e C++ non sono la stessa lingua. Non scrivere C# in C++ e C++ in C#. – jason
Si potrebbe utilizzare comporre la vostra booleani in una sequenza bool
e quindi applicare LINQ:
bool[] conditions = new bool[] { cond1, cond2, cond3, cond4 };
bool singleTrue = conditions.Count(cond => cond) == 1;
solo per due booleani, esclusivo o diventa molto più semplice:
bool singleTrue = cond1 != cond2;
Modifica: Per ottenere on-demand valutazione e corto circuito, è necessario promuovere la nostra sequenza bool
in una sequenza Func<bool>
(in cui ogni elemento è un delegato funzione incapsula la valutazione di una condizione):
IEnumerable<Func<bool>> conditions = // define sequence here
int firstTrue = conditions.IndexOf(cond => cond());
bool singleTrue = firstTrue != -1 &&
conditions.Skip(firstTrue + 1).All(cond => !cond());
quanto sopra frammento presuppone l'esistenza di un operatore IndexOf
predicato-based, che non è disponibile sotto la versione corrente di LINQ ma può essere definita come un metodo di estensione in questo modo:
public static int IndexOf<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
int i = 0;
foreach (T element in source)
{
if (predicate(element))
return i;
i++;
}
return -1;
}
campione d ata per il test (un punto di interruzione può essere impostato su ogni false
o true
a seguire di valutazione):
IEnumerable<Func<bool>> conditions = new Func<bool>[]
{
() =>
false,
() =>
true,
() =>
false,
() =>
false,
};
credo che questo sarebbe fare il trucco
int i= 0;
if ((!A || ++i <= 1) &&
(!B || ++i <= 1) &&
(!C || ++i <= 1) &&
... &&
(i == 1))
Se non ho pensato sbagliato su questo, questo if
sarà falso non appena i > 1
. Se i
non è mai incrementato e raggiungiamo l'ultimo condion, sarà falso dal i == 0
List<Func<Customer, bool>> criteria = new List<Func<Customer, bool>>();
criteria.Add(c => c.Name.StartsWith("B"));
criteria.Add(c => c.Job == Jobs.Plumber);
criteria.Add(c => c.IsExcellent);
Customer myCustomer = GetCustomer();
int criteriaCount = criteria
.Where(q => q(myCustomer))
// .Take(2) // optimization
.Count()
if (criteriaCount == 1)
{
}
implementazione Linq della firma del metodo di Jason:
public static bool IsExactlyOneTrue(IEnumerable<Func<bool>> conditions)
{
int passingConditions = conditions
.Where(x => x())
// .Take(2) //optimization
.Count();
return passingConditions == 1;
}
Ottima risposta. Può anche farlo senza relazione con un tipo specifico: 'var conditions = new List
Certo, stai solo spingendo le istanze specifiche nei criteri. La mia raccolta "criteri" ritarda la necessità di avere un'istanza applicabile ed è riutilizzabile per tutte le istanze quante ne hai. –
Questo approccio richiede la valutazione di tutte le condizioni, indipendentemente dal fatto che sia necessario. Preferisco un approccio che consenta cortocircuiti. – jason
La maggior parte di queste risposte saranno lavorare e avere ' buona performance'. Ma la risposta più semplice è:
if((A & !(B || C)) ||
(B & !(A || C)) ||
(C & !(A || B)))
{
...
}
si finisce per valutare A/B/C più di una volta quindi questo è veramente utile solo quando si dispone bools semplici.
- 1. rapido se o/e istruzione come pitone
- 2. Casella combinata se istruzione
- 3. Parentesi in django se istruzione
- 4. Quale costrutto "se" è più veloce - istruzione o operatore ternario?
- 5. stessa istruzione di assemblaggio ma diversa istruzione macchina
- 6. #Eval se istruzione nel ripetitore
- 7. Cercare di capire questo breve istruzione assembler, ma non capisco
- 8. multi condizione se istruzione C++
- 9. Questa istruzione macro è legale in C++ o qualcos'altro? E se è legale come funziona
- 10. DropDownListPer richiamata o istruzione if
- 11. Istruzione SQL Update ma usando pyodbc
- 12. excel - se cella non è vuota, quindi fare istruzione IF
- 13. Chiudi istruzione con; o no?
- 14. Istruzione mySQL condizionale. Se true UPDATE, se false INSERT
- 15. PHP Se istruzione con condizioni multiple
- 16. JSTL se-istruzione all'interno HTML-attributo
- 17. Riga singola se istruzione con 2 azioni
- 18. Se esiste o esiste?
- 19. Python se istruzione con condizioni multiple
- 20. Differenza tra istruzione e funzione
- 21. Molto lungo se istruzione in Python
- 22. istruzione lock non sembra funzionare
- 23. Convalida indice/vincolo univoco istruzione MERGE per riga o per istruzione?
- 24. MySQL istruzione Select, DOVE E 'IN' clausola
- 25. Come rappresentare più condizioni in una shell se istruzione?
- 26. Se la condizione di istruzione if verifica su! = "Indefinito" fallisce
- 27. Transazione SQL Server e istruzione SELECT
- 28. Socket.recv funziona ma non riceve o non legge?
- 29. inline if istruzione java, perché non funziona
- 30. prova se getJSONArray è null o non
@Tim S. Non è abbastanza corretto inserire la risposta nei commenti di diverse altre risposte. Cancellare quei commenti e postare la risposta come risposta e accettarne il giudizio dal voto - come intendeva Jeff. –