247 votes

Obtenir le nom de propriété sous forme de chaîne

(Voir ci-dessous la solution que j'ai créé à l'aide de la réponse que j'ai accepté)

Je suis d'essayer d'améliorer la maintenabilité du code impliquant la réflexion. L'application dispose d'une .NET Remoting interface de l'exposer (entre autres choses) une méthode appelée Exécuter pour accéder à des parties de l'application ne figurant pas dans son publié interface à distance.

Voici comment l'application désigne les propriétés (statique dans cet exemple) qui sont destinés à être accessible par l'intermédiaire de l'Exécuter:

RemoteMgr.ExposeProperty("SomeSecret", typeof(SomeClass), "SomeProperty");

Ainsi, un utilisateur distant peut appeler:

string response = remoteObject.Execute("SomeSecret");

et l'application serait d'utiliser la réflexion pour trouver SomeClass.SomeProperty et renvoie sa valeur sous forme de chaîne.

Malheureusement, si quelqu'un renomme SomeProperty et oublie de changer la 3ème parm de ExposeProperty(), il se casse de ce mécanisme.

J'ai besoin de l'équivalent de:

SomeClass.SomeProperty.GetTheNameOfThisPropertyAsAString()

à utiliser comme la 3ème parm dans ExposeProperty donc le refactoring prendrait soin de renomme.

Est-il un moyen de faire cela? Merci à l'avance.

Ok, voici ce que j'ai fini par créer (en fonction de la réponse que j'ai sélectionné et la question qu'il a référencés):

// <summary>
// Get the name of a static or instance property from a property access lambda.
// </summary>
// <typeparam name="T">Type of the property</typeparam>
// <param name="propertyLambda">lambda expression of the form: '() => Class.Property' or '() => object.Property'</param>
// <returns>The name of the property</returns>
public string GetPropertyName<T>(Expression<Func<T>> propertyLambda)
{
    var me = propertyLambda.Body as MemberExpression;

    if (me == null)
    {
        throw new ArgumentException("You must pass a lambda of the form: '() => Class.Property' or '() => object.Property'");
    }

    return me.Member.Name;
 }

Utilisation:

// Static Property
string name = GetPropertyName(() => SomeClass.SomeProperty);

// Instance Property
string name = GetPropertyName(() => someObject.SomeProperty);

Maintenant, avec ce cool capacité, il est temps de simplifier la ExposeProperty méthode. Polissage des poignées de porte est un travail dangereux...

Merci à tous.

64voto

Daniel Renshaw Points 12272

À l’aide de GetMemberInfo d’ici : http://stackoverflow.com/questions/671968/retrieving-property-name-from-lambda-expression vous pouvez faire quelque chose comme ceci :

``

17voto

Dan Bryant Points 19021

Il est bien connu hack pour extraire à partir de la lambda expression (ce qui est de la PropertyObserver classe, par Josh Smith, dans son MVVM fondation):

    private static string GetPropertyName
        (Expression<Func<TPropertySource, object>> expression)
    {
        var lambda = expression as LambdaExpression;
        MemberExpression memberExpression;
        if (lambda.Body is UnaryExpression)
        {
            var unaryExpression = lambda.Body as UnaryExpression;
            memberExpression = unaryExpression.Operand as MemberExpression;
        }
        else
        {
            memberExpression = lambda.Body as MemberExpression;
        }

        Debug.Assert(memberExpression != null, 
           "Please provide a lambda expression like 'n => n.PropertyName'");

        if (memberExpression != null)
        {
            var propertyInfo = memberExpression.Member as PropertyInfo;

            return propertyInfo.Name;
        }

        return null;
    }

Désolé, cela manquait un certain contexte. Cela faisait partie d'une classe où l' TPropertySource est la classe contenant la propriété. Vous pourriez faire la fonction générique en TPropertySource pour extraire à partir de la classe. Je vous recommande de prendre un coup d'oeil à l'intégralité du code de la MVVM de la Fondation.

9voto

Will Marcouiller Points 11649

La classe PropertyInfo devrait vous aider à atteindre cet objectif, si j’ai bien compris.

  1. Méthode Type.GetProperties()

Est-ce ce dont vous avez besoin ?

6voto

Robert Harvey Points 103562

Vous pouvez utiliser la réflexion pour obtenir les noms réels des propriétés.

http://www.CSharp-examples.net/Reflection-Property-Names/

Si vous avez besoin d’un moyen d’attribuer un « nom de la chaîne » à une propriété, pourquoi n’écrivez-vous pas un attribut que vous pouvez réfléchir plus pour obtenir le nom de chaîne ?

6voto

hypehuman Points 225

J’ai modifié votre solution à chaîne sur plusieurs propriétés :

Utilisation :

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