Wie kann ich feststellen, welche Schnittstelle von einem explizit implementierter Objekt Method verwiesen wird?

StackOverflow https://stackoverflow.com/questions/1962379

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.

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top