2015-11-20 3 views
7

Je voudrais comprendre comment fonctionne ce cas particulier. Voici le coup de l'article msdn où l'interface INotifyPropertyChanged est expliqué (https://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=EN-US&k=k%28System.ComponentModel.INotifyPropertyChanged%29;k%28TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5%29;k%28DevLang-csharp%29&rd=true) enter image description hereC# attribut personnalisé pour un paramètre de méthode - comment cela fonctionne?

Comme il est dit dans les lignes marquées il y a un moyen d'intercepter l'appel de méthode pour remplacer une valeur au lieu de ce qui est réel va en tant que paramètre? Je voudrais avoir une idée de ce que le code à faire ressemble à ceci. Je sais comment utiliser les attributs définis pour les propriétés et les autres membres de la classe, mais ce cas d'utilisation n'est pas clair pour moi.

Merci.

+0

Question similaire: [Comment utiliser les attributs de paramètre de méthode] (http://stackoverflow.com/questions/1715 0365/how-to-use-method-parameter-attributes) – cubrr

+0

Je ne pense pas que ce soit une question similaire. J'ai lu ce post. Il est demandé comment _validate_ value d'un paramètre pour quel attribut personnalisé est défini. Jon Skeet a répondu que ce n'était pas possible. Ici, je demande un exemple de code pour comprendre la solution implémentée comme pour l'interface INotifyPropertyChanged. –

Répondre

3

Il semble être une fonctionnalité implémentée dans le compilateur: il connaît cet attribut spécial et il substitue le nom de l'appelant à l'argument optionnel lorsqu'il a sa valeur par défaut.

Si vous voulez, vous pouvez vérifier l'implémentation de Roslyn. Bien qu'il ne soit pas toujours très simple à naviguer, il semble y avoir quelque chose here dans la fonction GetDefaultParameterValue (à partir de la ligne 844, au moins dans la révision en cours au moment de la rédaction - 0db946b):

si la le paramètre facultatif est annoté avec <see cref="CallerLineNumberAttribute"/>, <see cref="CallerFilePathAttribute"/> ou <see cref="CallerMemberNameAttribute"/>, et il n'y a aucun argument explicite correspondant, nous fournirons l'information d'appelant comme valeur de ce paramètre.

À la ligne 912 il y a une clause else if qui gère ce cas (les clauses if et else if avant que gérer les nouvelles fonctionnalités similaires CallerLineNumberAttribute et CallerFilePathAttribute):

... 
else if (parameter.IsCallerMemberName && ((callerSourceLocation = GetCallerLocation(syntax, enableCallerInfo)) != null)) 
... 

qui est finalement utilisé pour lier les paramètre:

BoundExpression memberNameLiteral = MakeLiteral(syntax, ConstantValue.Create(memberName), _compilation.GetSpecialType(SpecialType.System_String)); 
defaultValue = MakeConversion(memberNameLiteral, parameterType, false);