2009-08-20 14 views
17

Stavo scrivendo del codice oggi e qualcosa non funzionava come mi aspettavo.Override C# Problema di istruzioni condizionali

Perché il codice seguente viene eseguito anche se la condizione deve essere valutata su falso?

alt text http://img215.imageshack.us/img215/3011/agfewrf.gif

Ho provato a mettere parentesi attorno alle due condizioni, e la loro posizione di commutazione, ma l'EndedUsingApplication esegue addirittura ancora.

EDIT:

Non ha nulla a che fare con il || oppure & & operatori. Guardate questo ...

alt text http://img20.imageshack.us/img20/6655/aaaaaal.gif

Nessuno può imparare dal mio errore a meno che inserisco il codice colpevole, ecco che è.

public static bool operator ==(ActiveApplication a, ActiveApplication b) 
    { 
    if ((object)a == null || (object)b == null) 
     return false; 
    return a.process_name == b.process_name && a.window_title == b.window_title; 
    } 

    public static bool operator !=(ActiveApplication a, ActiveApplication b) 
    { 
    return a == b ? false : true; 
    } 

Ed ecco il codice di lavoro ...

public static bool operator ==(ActiveApplication a, ActiveApplication b) 
    { 
    // Casting to object class prevents this comparison operator being executed 
    // again and causing an infinite loop (which I think .NET detects and stops 
    // but it would still be a huge hole in the logic. 
    if ((object)a == null && (object)b == null) 
     return true; 
    if ((object)a == null^(object)b == null) 
     return false; 
    return a.process_name == b.process_name && a.window_title == b.window_title; 
    } 

    public static bool operator !=(ActiveApplication a, ActiveApplication b) 
    { 
    return a == b ? false : true; 
    } 

Il problema sembrava essere quando l'Operatore! = Ha ricevuto due valori nulli.

+0

potete inserire il codice? – danish

+0

@Jay Riggs: Bingo! Sì, si scopre che ho. C'è una cattiva logica in là che sta restituendo un risultato errato. Scrivi una risposta corretta e forse la contrassegnerò come risposta;) – Nippysaurus

+0

@Nippy - aggiungi come risposta! Grazie! –

risposta

51

Avete sovraccaricato !=?

+0

Vedere la domanda originale per la spiegazione. – Nippysaurus

+0

Wow, ottima chiamata. –

+0

Penso che ci sia una lezione da imparare qui –

3

Non so perché. Ma sei sicuro che l'applicazione in esecuzione sia compilata usando il codice che stai attraversando. Ho visto questo genere di cose quando il codice è diverso da quello che viene effettivamente eseguito.

1

Il programma è multiplo?

Ho visto situazioni in cui controllo un valore e poi cerco di usarlo solo per trovare il suo cambiamento. Quello che è successo è che un altro thread ha cambiato il valore dopo averlo controllato ma prima di usarlo.

1

Sei sicuro di essere effettivamente sulla linea che hai evidenziato? Puoi fare clic in giro nella finestra dello stack delle chiamate e fare in modo che qualsiasi parte della chiamata impili la linea "corrente" nel senso che puoi ottenere il valore delle variabili lì e così via.

Il punto è, forse EndedUsingApplication imposta ActiveApplication null, in modo che ActiveApplication non era nulla quando ha valutato il caso, ma ora è null quando si sta valutando nel debugger.

Hai inserito un punto di interruzione nella riga EndedUsingApplication (ActiveApplication) per assicurarti che ActiveApplication sia nullo prima di eseguire quella riga?

1

Penso che un approccio migliore è quello di utilizzare Object.ReferenceEquals in quanto è più esplicito:

public static bool operator ==(ActiveApplication a, ActiveApplication b) 
    { 
    // same reference so equals is true - will be true for null == null 
    if (object.ReferenceEquals(a, b)) 
     return true; 

    // one is null and the other is not 
    if (object.ReferenceEquals(a, null) || object.ReferenceEquals(b, null)) 
     return false; 

    // dealt with all combinations of null - compare fields 
    return a.process_name == b.process_name && a.window_title == b.window_title; 
    } 

    public static bool operator !=(ActiveApplication a, ActiveApplication b) 
    { 
    return !(a == b); 
    } 
Problemi correlati