2013-06-12 5 views
5

E 'possibile confrontare due oggetti senza conoscendo i loro tipi di box in fase di compilazione? Ad esempio, se ho un object{long} e object{int}, c'è un modo per sapere se i valori in scatola sono uguali?Confronta oggetti in scatola in C#

Il mio metodo recupera due generici object s e non c'è modo di sapere quali sono i loro tipi interni in fase di compilazione. In questo momento, il confronto viene effettuato dal seguente codice:

_keyProperties[x].GetValue(entity, null).Equals(keyValues[x]) 

in cui, per esempio, è un _keyProperties[x].GetValue(entity, null)object{long} e keyValues[x] è una object{int} (ma possono essere invertiti pure).

Ho bisogno di questo perché sto costruendo un deposito fittizio per i miei test di unità e ho iniziato includendo un'implementazione di repository generica come descritto here. Questa implementazione confronta due chiavi generiche false-DB nel suo metodo Find.

+1

Hai visto [questa risposta] (http: // StackOverflow .com/a/6669045/728795), in particolare la sua seconda parte? – Andrei

+0

Certo che l'ho fatto, ma sto ricevendo un 'System.InvalidCastException' con il messaggio" Impossibile convertire un oggetto nullo in un tipo di valore ". – frapontillo

+1

@frapontillo Hai solo bisogno di aggiungere un controllo null allora? –

risposta

2

Questo potrebbe essere troppo lento per il vostro caso, ma è possibile utilizzare dynamic di fare il test come il seguente codice illustra:

object obj1 = 1; 
object obj2 = 1.0; 

if (obj1.Equals(obj2)) 
    Console.WriteLine("Yes"); 
else 
    Console.WriteLine("No"); // Prints "No" as you'd expect. 

if ((dynamic) obj1 == (dynamic) obj2) 
    Console.WriteLine("Yes"); // Prints "Yes" because it handles trivial conversions. 
else 
    Console.WriteLine("No"); 

essere consapevoli del fatto che l'utilizzo di dynamic può essere lenta (anche se il codice generato per il supporto è memorizzato nella cache così almeno quella parte non viene eseguita più di una volta).

Inoltre può avere qualche problema se i tipi non sono collegati - see here for more discussion.

Per esempio, questo sarà un'eccezione:

object obj1 = "Hello"; 
object obj2 = 1.0; 

if ((dynamic) obj1 == (dynamic) obj2) // Throws an exception! 
    Console.WriteLine("Yes"); 
else 
    Console.WriteLine("No"); 
+0

Questa potrebbe essere una soluzione, ma sto effettuando il confronto all'interno di un albero di espressioni e "Un albero di espressioni potrebbe non contenere un'operazione dinamica" è l'errore di compilazione che ottengo. – frapontillo

+1

@frapontillo Ah questo è un peccato, mi dispiace! –

+0

Ancora, questo è divertente: esportando il codice comparativo all'interno di un metodo, il compilatore non si lamenta e il confronto funziona! Grazie mille! In realtà non mi interessa la velocità, in quanto il confronto verrà effettuato in test in cui non mi interessa più di tanto. – frapontillo