Wie kann ich feststellen, welche Schnittstelle von einem explizit implementierter Objekt Method verwiesen wird?
-
21-09-2019 - |
Frage
Ich habe ein MethodInfo
Objekt, das eine explizit implementierte Schnittstelle Methode darstellt, wie folgt.
MethodInfo GetMethod()
{
return typeof(List<>).GetMethod(
"System.Collections.IEnumerable.GetEnumerator",
BindingFlags.Instance | BindingFlags.NonPublic);
}
Wie kann ich diese Abfrage MethodInfo
Objekt der Schnittstellentyp es Geräte zu erhalten, ein Type
Objekt darstellt System.Collections.IEnumerable
? Die InterfaceMapping
Struktur stellt die inverse Operation, die immer MethodInfo
Objekt eines Typs, der Geräte eine bestimmte Schnittstelle, so dass wird nicht funktionieren.
Beachten Sie, dass dies ein konstruiertes Beispiel ist, wie ich klar die Methodennamen für diese Informationen analysieren kann. Ich möchte dies zu tun, wenn möglich zu vermeiden.
Lösung
Ich weiß nicht, von einer direkten Art und Weise, dies zu tun, aber man kann natürlich InterfaceMapping in umgekehrter Reihenfolge verwenden: iterate über alle von der Methode deklariert Typ implementierten Schnittstellen, zu überprüfen, ob die Methode in der Schnittstelle Karte ist für die Schnittstelle:
foreach (Type itf in method.DeclaringType.GetInterfaces())
{
if (method.DeclaringType.GetInterfaceMap(itf).TargetMethods.Any(m => m == method))
{
Console.WriteLine("match: " + itf.Name);
}
}
Obwohl dies ein wenig ineffizient erscheinen, implementieren die meisten Arten wenig genug Schnittstellen, dass es keine große Sache sein sollte. Schätzen Sie es ist nicht sehr elegant aber!
Andere Tipps
Tut mir leid, meine erste Antwort auf den ersten habe ich versucht, das Verfahren immer durch die InterfaceMap
Struktur und die Verfahren in , die Struktur eigentlich tun Bericht der Schnittstelle als DeclaringType
. Dann habe ich mit ihm gebastelt und wusste nicht, es auf subtile Weise gebrochen wurde mit der Methode, die Sie gebucht hatte den MethodInfo
zu erhalten.
Der Vorteil ist jedoch, dass dieser feine Unterschied zu der Erkenntnis geführt, dass der MethodInfo
für die Interface-Methode und die MethodInfo
für die Durchführung der Verfahren, sind nicht wirklich die gleiche Methode. Und bei einer weiteren Gedanken, ich bin eigentlich ziemlich sicher, dass Sie, was zu tun ist unmöglich, zuverlässig zu tun.
Explizite Schnittstellenimplementierungen in C # ist ein wenig syntaktischen Zucker über die Art und Weise funktioniert es wirklich in der CLR. In anderen Sprachen kann ein einzelnes konkretes Verfahren mehrere Interface-Methoden, um die gleiche Art und Weise implementieren eine konkrete Klasse mehrere Schnittstellentypen implementieren können. Zum Beispiel in VB.NET, es ist vollkommen legal, dies zu tun:
Public Overrides Function Baz() As String Implements IFoo.Foo, IBar.Bar
Hier haben Sie eine Methode, die zwei Schnittstellenmethoden explizit ist implementiert. Wenn es möglich wäre, die ursprüngliche Schnittstelle Klasse zu erhalten - oder sogar die Original-Interface-Methode - was würden Sie bekommen? Wie beheben Sie die Mehrdeutigkeit?
Ich bin kein Experte für die CLR-Interna, aber ich glaube, dass Schnittstellenkarten Einbahn sind. Wenn Sie eine Schnittstelle oder Methode implementieren, implizit oder explizit, erzeugt der Compiler eine Karte von die Schnittstelle die Umsetzung, und das ist alles immer muss es handle Methodenaufrufe gegen die Schnittstelle.
Denken Sie an den C # -Generated Methodennamen wie fast zufällig zu sein. Auch wenn der Methodenname System.Collections.IEnumerable.GetEnumerator
ist, das ist wirklich nur ein Name, und es gibt nicht wirklich keine Informationen über System.Collections.IEnumerable
in dem Verfahren codierte selbst.
Versuchen MethodInfo.DeclaringType
.