Frage

Ich möchte den Namen der Methode erhalten, die als Func delegiert wird.

Func<MyObject, object> func = x => x.DoSomeMethod();
string name = ExtractMethodName(func); // should equal "DoSomeMethod"

Wie kann ich erreichen das?

- Für prahlen -

Machen Sie ExtractMethodName auch mit einer Eigenschaft Aufruf arbeiten, es den Namen der Eigenschaft in diesem Fall zurückkehren zu müssen.

zB.

Func<MyObject, object> func = x => x.Property;
string name = ExtractMethodName(func); // should equal "Property"
War es hilfreich?

Lösung

Schauen Sie MA! Keine Ausdrucksbäume!

Hier ist eine schnelle, schmutzige und umsetzungsspezifische Version, die die Metadaten-Token aus dem IL-Stream des zugrunde liegenden Lambda und löst es packt.

private static string ExtractMethodName(Func<MyObject, object> func)
{
    var il = func.Method.GetMethodBody().GetILAsByteArray();

    // first byte is ldarg.0
    // second byte is callvirt
    // next four bytes are the MethodDef token
    var mdToken = (il[5] << 24) | (il[4] << 16) | (il[3] << 8) | il[2];
    var innerMethod = func.Method.Module.ResolveMethod(mdToken);

    // Check to see if this is a property getter and grab property if it is...
    if (innerMethod.IsSpecialName && innerMethod.Name.StartsWith("get_"))
    {
        var prop = (from p in innerMethod.DeclaringType.GetProperties()
                    where p.GetGetMethod() == innerMethod
                    select p).FirstOrDefault();
        if (prop != null)
            return prop.Name;
    }

    return innerMethod.Name;
}

Andere Tipps

Ich glaube nicht, dies im allgemeinen Fall möglich ist. Was passiert, wenn Sie hatte:

Func<MyObject, object> func = x => x.DoSomeMethod(x.DoSomeOtherMethod());

Was würden Sie erwarten?

Dass gesagt wird, könnten Sie Reflektion verwenden, um das Func-Objekt zu öffnen und sehen, was es im Innern tut, aber Sie werden nur in der Lage sein, es zu lösen für bestimmte Fälle.

Überprüfen Sie heraus meine Hack Antwort hier:

Warum gibt es kein `fieldof `oder` methodof` Operator in C #?

In der Vergangenheit habe ich es eine andere Art und Weise, die Func statt Expression<Func<...>> verwendet, aber ich war viel weniger zufrieden mit dem Ergebnis. Die MemberExpression verwendete, um das Feld in meiner fieldof Methode zu erkennen, wird ein PropertyInfo zurückkehren, wenn eine Eigenschaft verwendet wird.

Bearbeiten # 1: Das funktioniert für eine Teilmenge des Problems:

Func<object> func = x.DoSomething;
string name = func.Method.Name;

Edit # 2: Wer mich markiert eine zweite herunternehmen sollte zu erkennen, was hier vor sich geht. Die Ausdrucksbäume können implizit mit Lambda-Ausdrücke verwendet werden und ist der schnellste, zuverlässigste Weg, um die spezifischen angeforderten Informationen hier.

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