(Voir ci-dessous la solution que j'ai créée en utilisant la réponse que j'ai acceptée)
J'essaie d'améliorer la maintenabilité de certains codes impliquant la réflexion. L'application possède une interface .NET Remoting exposant (entre autres) une méthode appelée Exécuter pour accéder à des parties de l'application non incluses dans son interface distante publiée.
Voici comment l'application désigne les propriétés (statiques dans cet exemple) qui sont censées être accessibles via Execute:
RemoteMgr.ExposeProperty("SomeSecret", typeof(SomeClass), "SomeProperty");
Ainsi, un utilisateur distant pourrait appeler:
string response = remoteObject.Execute("SomeSecret");
et l'application utiliserait la réflexion pour trouver SomeClass.SomeProperty et retourner sa valeur sous forme de chaîne.
Malheureusement, si quelqu'un renomme SomeProperty et oublie de modifier le 3ème paramètre de ExposeProperty (), il rompt ce mécanisme.
J'ai besoin de l'équivalent de:
SomeClass.SomeProperty.GetTheNameOfThisPropertyAsAString()
à utiliser comme 3e paramètre dans ExposeProperty afin que les outils de refactoring se chargent des renommages.
Y a-t-il un moyen de faire cela? Merci d'avance.
D'accord, voici ce que j'ai fini par créer (en fonction de la réponse que j'ai sélectionnée et de la question à laquelle il a fait référence):
// <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;
}
Usage:
// Static Property
string name = GetPropertyName(() => SomeClass.SomeProperty);
// Instance Property
string name = GetPropertyName(() => someObject.SomeProperty);
Maintenant, avec cette fonctionnalité intéressante, il est temps de simplifier la méthode ExposeProperty. Le polissage des poignées de porte est un travail dangereux ...
Merci tout le monde.
la source
Réponses:
En utilisant GetMemberInfo à partir d'ici: En récupérant le nom de la propriété à partir d'une expression lambda, vous pouvez faire quelque chose comme ceci:
RemoteMgr.ExposeProperty(() => SomeClass.SomeProperty)
la source
GetMemberInfo
? Je ne trouve rien avec le package «Common Utilities» pour Microsoft Enterprise Library, qui est ce que MSDN semble indiquer contient cette méthode. Il y a un paquet "non officiel" mais être non officiel n'est pas inspirant. La réponse de JimC , basée sur celle-ci, est beaucoup plus concise et ne repose pas sur une bibliothèque apparemment indisponible.Avec C # 6.0, ce n'est plus un problème, comme vous pouvez le faire:
Cette expression est résolue à la compilation à
"SomeProperty"
.Documentation MSDN de nameof .
la source
const string
! IncroyableRaiseProperty
dans WPF! Utilisez RaisePropertyChanged (nom de (propriété)) au lieu de RaisePropertyChanged ("propriété")Il existe un hack bien connu pour l'extraire de l'expression lambda (il s'agit de la classe PropertyObserver, par Josh Smith, dans sa fondation MVVM):
Désolé, il manquait du contexte. Cela faisait partie d'une classe plus grande où se
TPropertySource
trouve la classe contenant la propriété. Vous pouvez rendre la fonction générique dans TPropertySource pour l'extraire de la classe. Je recommande de jeter un œil au code complet de la MVVM Foundation .la source
public static string GetPropertyName<TPropertySource>(Expression<Func<TPropertySource, object>> expression)
puis appeler comme ceci:var name = GetPropertyName<TestClass>(x => x.Foo);
D'accord, voici ce que j'ai fini par créer (en fonction de la réponse que j'ai sélectionnée et de la question à laquelle il a fait référence):
Usage:
la source
La classe PropertyInfo devrait vous aider à y parvenir, si je comprends bien.
Méthode Type.GetProperties ()
Est-ce ce dont vous avez besoin?
la source
Vous pouvez utiliser Reflection 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 chaîne" à une propriété, pourquoi n'écrivez-vous pas un attribut sur lequel vous pouvez réfléchir pour obtenir le nom de la chaîne?
la source
J'ai modifié votre solution pour enchaîner plusieurs propriétés:
Usage:
la source
Basé sur la réponse qui se trouve déjà dans la question et sur cet article: https://handcraftsman.wordpress.com/2008/11/11/how-to-get-c-property-names-without-magic-strings/ I présente ma solution à ce problème:
Et un test qui montre également l'utilisation par exemple et les propriétés statiques:
la source
Ancienne question, mais une autre réponse à cette question consiste à créer une fonction statique dans une classe d'assistance qui utilise CallerMemberNameAttribute.
Et puis utilisez-le comme:
la source
Vous pouvez utiliser la classe StackTrace pour obtenir le nom de la fonction actuelle (ou si vous placez le code dans une fonction, descendez d'un niveau et obtenez la fonction appelante).
Voir http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace(VS.71).aspx
la source
J'ai utilisé cette réponse avec grand effet: obtenir la propriété, sous forme de chaîne, à partir d'une expression <Func <TModel, TProperty >>
Je me rends compte que j'ai déjà répondu à cette question il y a quelque temps. Le seul avantage de mon autre réponse est qu'elle fonctionne pour les propriétés statiques. Je trouve la syntaxe dans cette réponse beaucoup plus utile car vous n'avez pas à créer une variable du type que vous souhaitez refléter.
la source
J'ai eu quelques difficultés à utiliser les solutions déjà suggérées pour mon cas d'utilisation spécifique, mais je l'ai finalement compris. Je ne pense pas que mon cas spécifique soit digne d'une nouvelle question, donc je poste ma solution ici pour référence. (Ceci est très étroitement lié à la question et fournit une solution pour toute autre personne ayant un cas similaire au mien).
Le code avec lequel je me suis retrouvé ressemble à ceci:
La partie importante pour moi est que dans la
CompanyControl
classe, le compilateur ne me permettra que de choisir une propriété booléenneICompanyViewModel
qui facilite la tâche des autres développeurs.La principale différence entre ma solution et la réponse acceptée est que ma classe est générique et je veux seulement faire correspondre les propriétés du type générique qui sont booléennes.
la source
C'est comme ça que je l'ai implémenté, la raison derrière est que si la classe dont vous voulez obtenir le nom de son membre n'est pas statique, vous devez créer un instantané de cela et ensuite obtenir le nom du membre. si générique vient ici pour aider
l'utilisation est comme ça
la source