2010-11-12 13 views
9

Potrzebuję sprawdzić równość między dwoma MethodInfos. W rzeczywistości są to dokładnie te same metody MethodInfo, z wyjątkiem ReflectedType (to znaczy, że DeclaringType jest taki sam, a metody powinny w rzeczywistości mieć to samo ciało). Jest na to wiele sposobów, ale szukam najbardziej wydajnego.Równość MethodInfo dla Zgłaszanie typu

Teraz mam:

public static bool AreMethodsEqualForDeclaringType(this MethodInfo first, MethodInfo second) 
    { 
     first = first.ReflectedType == first.DeclaringType ? first : first.DeclaringType.GetMethod(first.Name, first.GetParameters().Select(p => p.ParameterType).ToArray()); 
     second = second.ReflectedType == second.DeclaringType ? second : second.DeclaringType.GetMethod(second.Name, second.GetParameters().Select(p => p.ParameterType).ToArray()); 
     return first == second; 
    } 

Jest to rodzaj drogie, więc zastanawiam się, czy jest jakiś lepszy sposób ...

powinienem być porównanie dwóch metod zamiast ciał? na przykład.

Dzięki.

+0

Dlaczego nie można po prostu porównać typy deklarujących bezpośrednio bez porównywania rąbka do odbitych typów? Chciałbym również wiedzieć, dlaczego tak się dzieje. – jgauffin

+1

Zdecydowanie można porównać typy deklarujące, ale jest to droższe, ponieważ wymaga to wywołania metody GetParameters(), natomiast jeśli typy ReflectedTypes są równe, mogę po prostu wykonać regularną kontrolę równości. – Jeff

+1

Muszę to zrobić, ponieważ mam klasy Proxy utworzone przez EntityFramework w czasie wykonywania, nad którym zastanawiam się. – Jeff

Odpowiedz

3

Chyba zostawię moją odpowiedź jako odpowiedź na pytanie ...

Jedną rzeczą, aby pamiętać:

first.GetMethodBody() == second.GetMethodBody() 

nie działa ... więc jedynym rozwiązaniem mam znaleziono do tej pory to:

public static bool AreMethodsEqualForDeclaringType(this MethodInfo first, MethodInfo second) 
{ 
    first = first.ReflectedType == first.DeclaringType ? first : first.DeclaringType.GetMethod(first.Name, first.GetParameters().Select(p => p.ParameterType).ToArray()); 
    second = second.ReflectedType == second.DeclaringType ? second : second.DeclaringType.GetMethod(second.Name, second.GetParameters().Select(p => p.ParameterType).ToArray()); 
    return first == second; 
} 
+0

ciało metody ma bajt [], który jest IL ciała metody, można porównać bajt po bajcie zamiast używać tylko "==". –

+0

@Jeff. Wiem, że spóźniam się na imprezę jakieś dziesięć lat, ale ... czy nadal używasz tego kodu? Potrzebuję czegoś podobnego, ale nie chcę wymyślać koła. [Ayende ma post na ten temat] (http://ayende.com/blog/2658/method-equality), który na pewno musiałeś zobaczyć. Doceń wszelkie opinie. Pozdrowienia – Berryl

1

Byłoby porównując pomocy MetadataToken i Module?

Dokumentacja MetadataToken opisuje ją jako: "Wartość, która w połączeniu z modułem jednoznacznie identyfikuje element metadanych."

Do tej pory przekonałem się, że działa on przy porównywaniu instancji MemberInfo typu equal-except-for-ReflectedType. Ale nie przetestowałem go pod kątem przypadków, takich jak ogólne definicje metod.

+0

Dzięki, ale to jest dokładnie w przypadku, gdy nie działa. – Jeff

0

ten kod działa przy próbie równej klasy i interfejsu Metoda:

static bool EquelMethods(MethodInfo method1, MethodInfo method2) 
    { 
     var find = method1.DeclaringType.GetMethod(method2.Name, method2.GetParameters().Select(p => p.ParameterType).ToArray()); 
     return find != null; 
    }