web-dev-qa-db-fra.com

Comment puis-je obtenir la valeur de membreInfo?

Comment puis-je obtenir la valeur d'un objet MemberInfo? .Name Retourne le nom de la variable, mais j'ai besoin de la valeur.

Je pense que vous pouvez le faire avec FieldInfo mais je n'ai pas d'extrait, si vous savez faire cela, pouvez-vous fournir un extrait?

Merci!

31
Keith Fitzgerald

Voici un exemple pour les champs, en utilisant fieldinfo.getvalue :

using System;
using System.Reflection;

public class Test
{
    // public just for the sake of a short example.
    public int x;

    static void Main()
    {
        FieldInfo field = typeof(Test).GetField("x");
        Test t = new Test();
        t.x = 10;

        Console.WriteLine(field.GetValue(t));
    }
}

Le code similaire fonctionnera pour les propriétés à l'aide de PropertyInfo.getvalue () - Bien que vous n'ayez également besoin de transmettre les valeurs des paramètres des propriétés. (Il n'y aura pas de propriétés "normales" C #, mais c # Les indexateurs comptent également des propriétés aussi en ce qui concerne le cadre.) Pour des méthodes, vous devez appeler Invoke si vous voulez appeler la méthode et utiliser la valeur de retour.

32
Jon Skeet

Bien que je suis généralement d'accord avec le point de Marc à propos de ne pas refléter les champs, il y a des moments où cela est nécessaire. Si vous souhaitez refléter un membre et que vous ne vous souciez pas de savoir s'il s'agit d'un champ ou d'une propriété, vous pouvez utiliser cette méthode d'extension pour obtenir la valeur (si vous souhaitez le type au lieu de la valeur, reportez-vous à la réponse de Nawful Cette question ):

    public static object GetValue(this MemberInfo memberInfo, object forObject)
    {
        switch (memberInfo.MemberType)
        {
            case MemberTypes.Field:
                return ((FieldInfo)memberInfo).GetValue(forObject);
            case MemberTypes.Property:
                return ((PropertyInfo)memberInfo).GetValue(forObject);
            default:
                throw new NotImplementedException();
        }
    } 
22
Eric Hewitt

La réponse de Jon est idéale - une seule observation: dans le cadre de la conception générale, je voudrais:

  1. Généralement Évitez de réfléchir à des membres non publics
  2. évitez d'avoir des champs publics (presque toujours)

Le résultat de ces deux est que en général , il vous suffit de réfléchir contre les propriétés publiques (vous ne devriez pas appeler des méthodes à moins que vous sachiez ce qu'ils font; biens Les getters sont attendus être idempotent [Paresseux chargement de côté]). Donc, pour un PropertyInfo ceci est juste prop.GetValue(obj, null);.

En fait, je suis un grand fan de System.ComponentModel, alors je serais tenté d'utiliser:

    foreach(PropertyDescriptor prop in TypeDescriptor.GetProperties(obj))
    {
        Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));
    }

ou pour une propriété spécifique:

    PropertyDescriptor prop = TypeDescriptor.GetProperties(obj)["SomeProperty"];
    Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));

Un avantage de System.ComponentModel Est-ce que cela fonctionnera avec des modèles de données abstraits, tels que la manière dont a DataView expose des colonnes comme propriétés virtuelles; Il y a d'autres astuces aussi (comme astuces de performance ).

11
Marc Gravell