Quelle est la meilleure façon de savoir si une méthode est une propriété de Policy Injection?

StackOverflow https://stackoverflow.com/questions/73467

Question

J'ai un gestionnaire personnalisé appliqué à une classe (à l'aide du bloc d'application d'injection de règles dans entlib 4) et j'aimerais savoir si la méthode d'entrée est une propriété lors de l'appel de Invoke. Voici à quoi ressemble mon gestionnaire.

[ConfigurationElementType(typeof(MyCustomHandlerData))]
public class MyCustomHandler : ICallHandler
{
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        if (input.MethodBase.IsPublic && (input.MethodBase.Name.Contains("get_") || input.MethodBase.Name.Contains("set_")))
        {
            Console.WriteLine("MyCustomHandler Invoke called with input of {0}", input.MethodBase.Name);
        }
        return getNext().Invoke(input, getNext);
    }

    public int Order { get; set; }
}

Comme vous pouvez le constater à partir de mon exemple de code, le meilleur moyen auquel j'ai pensé jusqu'à présent consiste à analyser le nom de la méthode. N'y a-t-il pas une meilleure façon de faire cela?

Était-ce utile?

La solution

Vous pouvez également vérifier que IsSpecialName est vrai. ce sera le cas dans une propriété (entre autres)

Au niveau il, les méthodes sont exposées comme suit (en utilisant Environment.ExitCode comme exemple):

.method public hidebysig specialname static int32 get_ExitCode() cil managed
.method public hidebysig specialname static void set_ExitCode(int32 'value') cil managed

Si vous voulez avoir l’imagination, vous pouvez vérifier après avoir extrait le nom que cette propriété existe, mais pour être honnête

if (m.IsSpecialName && (m.Attributes & MethodAttributes.HideBySig) != 0)) 

ainsi que commence par get_ ou set_, alors vous devriez être bon même pour les personnes qui utilisent des noms désagréables (simuler le hidebysig est assez facile, simuler le IsSpecialName serait très délicat)

Rien n'est garanti cependant. Quelqu'un pourrait émettre une classe avec une méthode set_Foo qui ressemblait à une vraie méthode set, mais qui n'était en réalité pas un jeu sur une propriété en lecture seule. À moins que vous ne vérifiiez si la propriété CanRead / CanWrite également.

Cela me semble une folie pour vous bien que vous ne vous attendiez pas à un contournement délibéré. Un simple utilitaire / méthode d’extension sur MethodInfo qui utilise cette logique ne serait pas trop difficile et inclure IsSpecialName couvrirait presque certainement tous vos besoins.

Autres conseils

Vous pouvez vérifier la propriété IsSpecialName; ce sera vrai pour les accesseurs et les setters de propriété. Toutefois, cela sera également vrai pour d’autres méthodes spéciales, telles que les surcharges d’opérateurs.

Je ne connais pas bien ce bloc d'application, mais en supposant que la propriété MethodBase soit du type System.Reflection.MethodBase, vous pouvez consulter la propriété IsSpecialName.

System.Reflection.MethodBase.IsSpecialName sur MSDN

Quelques-uns d'entre vous ont mentionné l'utilisation de l'option "IsSpecialName". propriété du type MethodBase. S'il est vrai que the retournera vrai pour la propriété " obtient " ou "sets", il renverra également la valeur true pour les surcharges d'opérateurs telles que add_EventName ou remove_EventName. Vous devrez donc examiner d'autres attributs de l'instance MethodBase pour déterminer s'il s'agit d'un accesseur de propriété. Malheureusement, si tout ce que vous avez est une référence à une instance de MethodBase (ce qui, je crois, concerne les comportements d'interception dans le cadre Unity), il n'y a pas de véritable "nettoyage". manière de déterminer s’il s’agit d’un getter ou d’un getter de propriétés La meilleure façon que j'ai trouvée est la suivante:

C #:

bool IsPropertySetter(MethodBase methodBase){
     return methodBase.IsSpecialName && methodBase.Name.StartsWith("set_");
}

bool IsPropertyGetter(MethodBase methodBase){
     return methodBase.IsSpecialName && methodBase.Name.StartsWith("get_");
}

VB:

 Private Function IsPropertySetter(methodBase As MethodBase) As Boolean

      Return methodBase.IsSpecialName AndAlso methodBase.Name.StartsWith("set_")

 End Function

 Private Function IsPropertyGetter(methodBase As MethodBase) As Boolean

      Return methodBase.IsSpecialName AndAlso methodBase.Name.StartsWith("get_")

 End Function

Il est un peu tard mais d’autres liront aussi. Outre IsSpecialName et la recherche du préfixe set_ (les opérateurs ont op_, subscr./remov. A add_, remove_), vous pouvez vérifier si method correspond à l'une des méthodes de propriétés suivantes:

    bool isProperty = method.ReflectedType.GetProperties().FirstOrDefault(p => 
        p.GetGetMethod().GetHashCode() == method.GetHashCode() 
        || p.GetSetMethod().GetHashCode() == method.GetHashCode())!=null;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top