Question

J'aimerais connaître le nom de la méthode déléguée en tant que Func.

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

Comment puis-je y parvenir?

- Pour se vanter -

Assurez-vous que ExtractMethodName fonctionne également avec un appel de propriété, en renvoyant le nom de la propriété dans cette instance.

par exemple.

Func<MyObject, object> func = x => x.Property;
string name = ExtractMethodName(func); // should equal "Property"
Était-ce utile?

La solution

Regarde maman! Pas d'arbres d'expression!

Voici une version rapide, incorrecte et spécifique à l'implémentation qui récupère le jeton de métadonnées du flux IL du lambda sous-jacent et le résout.

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;
}

Autres conseils

Je ne pense pas que cela soit possible dans le cas général. Et si vous aviez:

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

Qu'attendriez-vous?

Cela étant dit, vous pouvez utiliser la réflexion pour ouvrir l'objet Func et voir ce qu'il fait à l'intérieur, mais vous ne pourrez le résoudre que dans certains cas.

Découvrez ma réponse hack ici:

Pourquoi n'y a-t-il pas de `champ of Opérateur `ou` methodof` en C #?

Dans le passé, je l’utilisais d’une autre manière qui utilisait Func au lieu de Expression<Func<...>>, mais j’étais beaucoup moins satisfait du résultat. Le MemberExpression utilisé pour détecter le champ dans ma fieldof méthode renverra un PropertyInfo lorsqu'une propriété est utilisée.

Éditer # 1: Cela fonctionne pour un sous-ensemble du problème:

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

Éditer # 2: Celui qui m'a marqué devrait prendre une seconde pour se rendre compte de ce qui se passe ici. Les arbres d’expression peuvent être utilisés implicitement avec les expressions lambda et constituent le moyen le plus rapide et le plus fiable d’obtenir ici les informations spécifiques demandées.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top