43 votes

Pourquoi n'est-il pas un "champ" ou " methodof` opérateur en C#?

Ils pourraient être utilisés comme suit:

FieldInfo field = fieldof(string.Empty);
MethodInfo method1 = methodof(int.ToString);
MethodInfo method2 = methodof(int.ToString(IFormatProvider));

fieldof a pu être réalisé pour IL comme:

ldtoken <field>
call FieldInfo.GetFieldFromHandle

methodof a pu être réalisé pour IL comme:

ldtoken <method>
call MethodBase.GetMethodFromHandle

Chaque fois que l' typeof opérateur est utilisé, vous obtenez une parfaite Trouver Toutes les Références des résultats. Malheureusement, dès que vous aller aux champs ou méthodes, vous vous retrouvez avec nasty hacks. Je pense que vous pouvez faire ce qui suit... ou vous pouvez revenir à l'obtention d'un champ par son nom.

public static FieldInfo fieldof<T>(Expression<Func<T>> expression)
{
    MemberExpression body = (MemberExpression)expression.Body;
    return (FieldInfo)body.Member;
}

public static MethodInfo methodof<T>(Expression<Func<T>> expression)
{
    MethodCallExpression body = (MethodCallExpression)expression.Body;
    return body.Method;
}

public static MethodInfo methodof(Expression<Action> expression)
{
    MethodCallExpression body = (MethodCallExpression)expression.Body;
    return body.Method;
}

public static void Test()
{
    FieldInfo field = fieldof(() => string.Empty);
    MethodInfo method1 = methodof(() => default(string).ToString());
    MethodInfo method2 = methodof(() => default(string).ToString(default(IFormatProvider)));
    MethodInfo method3 = methodof(() => default(List<int>).Add(default(int)));
}

35voto

MagnatLU Points 2815

Vous pouvez effectivement éviter d'utiliser à la fois la réflexion et les lambdas (.NET Framework 2.0). Considérons la classe suivante:

public class methodof<T>
{
    private MethodInfo method;

    public methodof(T func)
    {
        Delegate del = (Delegate)(object)func;
        this.method = del.Method;
    }

    public static implicit operator methodof<T>(T methodof)
    {
        return new methodof<T>(methodof);
    }

    public static implicit operator MethodInfo(methodof<T> methodof)
    {
        return methodof.method;
    }
}

et son utilisation:

MethodInfo writeln = (methodof<Action>)Console.WriteLine;
MethodInfo parse = (methodof<Func<string, int>>)int.Parse;

22voto

Jason Points 11332

Eric Lippert (sur le C# de l'équipe de conception) a une excellente présentation/discussion sur ce sujet ici. Pour citer:

C'est une fonctionnalité impressionnante que presque tout le monde impliqué dans le processus de conception souhaite que nous pourrions faire, mais il y a des bonnes pratiques raisons pour lesquelles nous choisissons de ne pas. Si il arrive un jour où la concevoir et de la mettre en œuvre, c'est la meilleure manière pour nous de passer notre budget limité, nous le ferons. Jusqu'alors, l'utilisation de la Réflexion.

6voto

Terence Points 142

@280Z28 - nous venions de Nous asseoir à comprendre comment le faire quand j'ai trouvé votre question et de code. Nous avons besoin d'un PropertyOf méthode donc je l'ai ajouté. Ici, il est dans le cas où quelqu'un d'autre en a besoin. Thx pour la grande question.

     public static PropertyInfo PropertyOf<T>(Expression<Func<T>> expression)
    {
        MemberExpression body = (MemberExpression)expression.Body;
        PropertyInfo pi = body.Member as PropertyInfo;
        if (pi != null)
        {
            return pi;
        }
        else throw new ArgumentException("Lambda must be a Property.");
    } 

      [TestMethod()]
    public void MethodofPropertyOfTest<T>()
    {

        string foo = "Jamming";
        MethodInfo method1 = ReflectionHelper.Methodof(() => default(string).ToString());
        PropertyInfo prop = ReflectionHelper.PropertyOf(() => default(string).Length);
        Assert.AreEqual(method1.Invoke(foo, null), "Jamming");
        Assert.AreEqual(prop.GetGetMethod().Invoke(foo, null), foo.Length);
    }

0voto

IlPADlI Points 21

c'est un type générique de la version, qui peuvent utiliser la touche F2 pour renommer et pas besoin de modifier existait code dans l'exemple, le nom de la méthode est GetPKValue

var typFactory = typeof(FormFieldFactory<>).MakeGenericType(entity.GetType());
var methodName = new Func<object, object>(FormFieldFactory<object>.GetPKValue).Method.Name;

var theMethod =
    (Func<object, object>)Delegate.CreateDelegate(
        typeof(Func<object, object>)
        , typFactory.GetMethod(methodName)
    );

-2voto

Spencer Ruport Points 24589

J'rue de la journée lorsque la réflexion devient facile. Si vous pensiez que le SQL dynamique était mauvais, cela permettrait d'aboutir à quelque chose une dizaine de fois pire.

Imaginez, le changement du nom de la propriété et de l'avoir à vous soucier des erreurs d'exécution. /frisson

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X