2009-06-25 6 views
22

Je souhaite conserver une propriété entre les publications dans une application ASP.Net. Le fait déjà:Récupère le nom de la propriété dans le setter

public int MyIndex 
{ 
    get 
    { 
     return (int)Session[ToString() + "MyIndex"]; 
    } 
} 

mais préféreraient quelque chose comme:

public int MyIndex 
{ 
    get 
    { 
     return (int)Session[ToString() + #code_that_returns_property_name#]; 
    } 
} 

Setter omis, mais il pousse juste valeur en session en utilisant la même chaîne. Existe-t-il un moyen d'utiliser la réflexion ou une meilleure solution différente?

+0

On dirait que nous avons enfin un peu [à venir de bonbons syntaxique] (http://blogs.msdn.com/b/csharpfaq/archive/2014/11/20/new-features-in-c-6. aspx) pour résoudre ce problème: "Souvent, vous devez fournir une chaîne qui nomme un élément de programme: lorsque vous lancez une ArgumentNullException, vous voulez nommer l'argument de culpabilité, lorsque vous déclenchez un événement PropertyChanged, vous voulez nommer la propriété modifiée, etc. " 'if (x == null) lancer une nouvelle ArgumentNullException (nameof (x));' – JMD

Répondre

24
public static int Dummy { 
    get { 
     var propertyName = MethodBase.GetCurrentMethod().Name.Substring(4); 
     Console.WriteLine(propertyName); 
     return 0; 
    } 
} 
+1

GetCurrentMethod() a retourné une exception System.ArgumentException pour moi ... –

+0

Non, cela a fonctionné. Je ne sais pas d'où vient cette exception. Fonctionne bien maintenant. Juste ce dont j'avais besoin. –

+4

Pour l'amour de Dieu, non! Le résultat est cinq fois plus long et 100 fois plus obscur que ce qu'il a remplacé! À moins que vous ne changiez continuellement d'avis sur ce que vous appelez cette propriété, c'est une idée ridicule. (... IMHO) –

13

Non, il n'y a pas un moyen simple de faire ce que vous voulez faire. Je pense que vous êtes beaucoup mieux avec le code que vous avez déjà écrit.

Éditer:Cette réponse a reçu pas mal de downvotes et je comprends pourquoi. Alors qu'il est possible de faire ce que le PO veut faire peut-être que nous devrions tous nous arrêter et de penser si c'est conseillé de le faire. Pour paraphraser les mots immortels de Dr. Ian Malcom, ce n'est pas parce que vous pouvez faire quelque chose que vous devriez le faire.

+0

Pourquoi le vote négatif? c'est la réponse la plus sensée ... :) +1 de moi. –

+1

+1 de ma part, c'est une idée INSANE. Si vous trouvez que vous devez le faire beaucoup, et que le nom change constamment, la gestion devient un fardeau, puis utilisez un fichier .tt pour coder les déclarations de propriétés ou quelque chose comme ça. –

+0

+1 pour ceci et la réponse acceptée. Je peux voir pourquoi OP voudrait faire ceci, et le facteur atténuant: Si la propriété en question est juste une sur 40, il y a quelque chose à dire pour une seule implémentation qui est découplée des 40 noms de propriété codés en dur. Le facteur atténuant est, bien sûr, si l'OP sait que ces propriétés ne sont définies qu'une fois ou un petit nombre de fois, les performances à ce niveau sont discutables. Évitez l'optimisation prématurée. – JMD

7

Vous pouvez utiliser MethodInfo.GetCurrentMethod() Nom pour revenir le nom de la méthode actuelle.

public int MyIndex 
{ 
    get 
    { 
     return (int)Session[ToString() + MethodInfo.GetCurrentMethod().Name]; 
    } 
} 

Comme les propriétés sont mises en œuvre en tant que méthodes sous le capot, qui renverra un nom comme "get_MyIndex". Si vous ne voulez pas le « get_ » partie, vous pouvez sous-chaîne quelques caractères:

public int MyIndex 
{ 
    get 
    { 
     return (int)Session[ToString() + MethodInfo.GetCurrentMethod().Name.Substring(4)]; 
    } 
} 
1

Vous devriez plutôt utiliser la propriété ViewState de votre commande:

public int MyIndex { 
    get { 
     object index = ViewState["MyIndex"]; 
     return (null == index) ? -1 : (int)index; 
    } 
    set { 
     ViewState["MyIndex"] = value; 
    } 
} 
2

Vous pouvez utiliser une expression arbre pour obtenir le nom du membre. C'est un peu un jarret mais ça marche. Voici le code.

private string GetPropertyName<TValue>(Expression<Func<BindingSourceType, TValue>> propertySelector) 
{ 
    var memberExpression = propertySelector.Body as MemberExpression; 
    if (memberExpression != null) 
    { 
     return memberExpression.Member.Name; 
    } 
    else 
    { 
     return string.empty;  
    } 
} 

Avec ce code, vous pouvez effectuer les opérations suivantes

return (int)Session[ToString() + GetPropertyName(MyIndex)]; 

code sans pitié volé la réponse de Romain sur le fil suivant

+0

Quelle solution élégante! +1 –

+0

Impossible de résoudre le symbole 'BindingSourceType' Ceci est un projet ASP.Net 3.5 ... –

+0

Si vous lisez la réponse d'origine de l'autre thread, il indique que BindingSourceType est le nom de classe qui contient la propriété. Vous devez utiliser le nom de la classe à laquelle appartient la propriété MyIndex. – adrianbanks

9

En utilisant CallerMemberName est beaucoup plus rapide et il peut être copié et collé facilement pour des propriétés supplémentaires.

private static object GetSessionValue([CallerMemberName]string propertyName = "") 
{ 
    return Session[propertyName]; 
} 

private static void SetSessionValue(object value, [CallerMemberName]string propertyName = "") 
{ 
    Session[propertyName] = value; 
} 

public int MyIndex 
{ 
    get { return (int)GetSessionValue(); } 
    set { SetSessionValue(value); } 
} 
+0

Cette réponse est la meilleure façon de procéder car elle fonctionne à la compilation et non à l'exécution. – EvilTak

Questions connexes