2013-06-12 12 views
5

Czy można porównać dwa obiekty bez znając ich typy pudełkowe w czasie kompilacji? Na przykład, jeśli mam object{long} i object{int}, czy istnieje sposób sprawdzenia, czy wartości w ramkach są równe?Porównaj obiekty w pudełku w C#

Moja metoda pobiera dwa ogólne object s, i nie ma sposobu, aby dowiedzieć się, jakie są ich wewnętrzne typy podczas kompilacji. Teraz, porównania dokonuje się za pomocą następującego kodu:

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

gdzie, powiedzmy, _keyProperties[x].GetValue(entity, null) jest object{long} i keyValues[x] jest object{int} (ale mogą być odwrócone, jak również).

Potrzebuję tego, ponieważ buduję fałszywe repozytorium dla testów jednostkowych, a ja zacząłem od włączenia ogólnej implementacji repozytorium zgodnie z opisem here. Ta implementacja porównuje dwa generyczne fałszywe-klucze DB w metodzie Find.

+1

Widziałeś [ta odpowiedź] (http: // stackoverflow .com/a/6669045/728795), szczególnie jego druga część? – Andrei

+0

Oczywiście, że tak, ale dostaję "System.InvalidCastException" z komunikatem "Nie można przekonwertować obiektu zerowego na typ wartości". – frapontillo

+1

@frapontillo Czy wystarczy dodać czek zerowy? –

Odpowiedz

2

To może być zbyt powolny w Twoim przypadku, ale można użyć dynamic zrobić test jak poniższy kod demonstruje:

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

Należy pamiętać, że używanie dynamic może być powolna (chociaż wygenerowany kod do wsparcia jest zbuforowany, więc przynajmniej część nie jest wykonywana więcej niż jeden raz).

Również może mieć pewne problemy jeśli typy nie są powiązane - see here for more discussion.

Na przykład, będzie to wyjątek:

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

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

To może być rozwiązanie, ale robię porównanie wewnątrz drzewa wyrażeń, a "Drzewo wyrażeń może nie zawierać operacji dynamicznej" jest błędem kompilacji, który dostaję. – frapontillo

+1

@frapontillo Ah, szkoda, przepraszam! –

+0

Nadal jest to zabawne: eksportując kod porównania wewnątrz metody kompilator nie żartuje, a porównanie działa! Dziękuję Ci bardzo! Naprawdę nie dbam o prędkość, ponieważ porównanie zostanie przeprowadzone w testach, w których tak bardzo mnie to nie obchodzi. – frapontillo