web-dev-qa-db-fra.com

Définir / obtenir les propriétés de la classe par nom de chaîne

Ce que j'essaie de faire est de définir la valeur de la propriété dans une classe à l'aide d'une chaîne. Par exemple, ma classe a les propriétés suivantes:

myClass.Name
myClass.Address
myClass.PhoneNumber
myClass.FaxNumber

Tous les champs sont de type string donc je sais à l'avance que c'est toujours une chaîne. Maintenant, je veux pouvoir définir les propriétés en utilisant une chaîne comme vous le feriez avec un objet DataSet. Quelque chose comme ça:

myClass["Name"] = "John"
myClass["Address"] = "1112 River St., Boulder, CO"

Idéalement, je veux simplement assigner une variable, puis définir la propriété en utilisant le nom de chaîne de la variable:

string propName = "Name"
myClass[propName] = "John"

Je lisais sur la réflexion et peut-être que c'est la façon de le faire mais je ne sais pas comment s'y prendre pour la mettre en place tout en conservant l'accès à la propriété intact dans la classe. Je veux toujours pouvoir utiliser:

myClass.Name = "John"

Tous les exemples de code seraient vraiment géniaux.

66
Patratacus

Vous pouvez ajouter la propriété de l'indexeur, un pseudocode:

public class MyClass 
{
     public object this[string propertyName] 
     {
        get{
           // probably faster without reflection:
           // like:  return Properties.Settings.Default.PropertyValues[propertyName] 
           // instead of the following
           Type myType = typeof(MyClass);                   
           PropertyInfo myPropInfo = myType.GetProperty(propertyName);
           return myPropInfo.GetValue(this, null);
        }
        set{
           Type myType = typeof(MyClass);                   
           PropertyInfo myPropInfo = myType.GetProperty(propertyName);
           myPropInfo.SetValue(this, value, null);

        }

     }
}
89
Tigran

Vous pouvez ajouter un indexeur à votre classe et utiliser la réflexion pour améliorer les propriétés:

using System.Reflection;

public class MyClass {

    public object this[string name]
    {
        get
        {
            var properties = typeof(MyClass)
                    .GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (var property in properties)
            {
                if (property.Name == name && property.CanRead)
                    return property.GetValue(this, null);
            }

            throw new ArgumentException("Can't find property");

        }
        set {
            return;
        }
    }
}
3
Dennis Traub