Paul Ruane
Paul Ruane

Reputation: 38620

Identify whether a MethodInfo instance is a property accessor

I am writing a decorating proxy using Castle DynamicProxy. I need the proxy's interceptor to intercept only property writes (not reads) so I am checking the name of the method thusly:

public void Intercept(IInvocation invocation)
{
    if (invocation.Method.Name.StartsWith("set_")
    {
        // ...
    }

    invocation.Proceed();
}

Now this works fine but I don't like the fact my proxy has intimate knowledge of how properties are implemented: I'd like to replace the method name check with something akin to:

if (invocation.Method.IsPropertySetAccessor)

Unfortunately my Google-fu has failed me. Any ideas?

Upvotes: 19

Views: 6929

Answers (6)

Marc Gravell
Marc Gravell

Reputation: 1063864

There isn't any voodoo of which I'm aware. You could, perhaps, strip the set_, look for a property with that name, and compare the MethodInfo instance (invocation.Method) to the property accessor (GetSetMethod()) - however, I can't honestly say (without checking) whether you will get the same MethodInfo instance (even if it is the same method).

if(method.IsSpecialName && method.Name.StartsWith("set_"))
{
    var prop = typeof (Foo).GetProperty(method.Name.Substring(4),
           BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
    var accessor = prop.GetSetMethod();
    bool isSame = accessor == method;
}

Upvotes: 7

dowhilefor
dowhilefor

Reputation: 11051

I'm not sure what kind of type the invocation.Method is, but if you can get the PropertyInfo you can use the IsSpecialName. Unfortunately this tells not only if the property is a set_ or _get but also if it is an overloaded operator.

Upvotes: 4

Heinzi
Heinzi

Reputation: 172438

You could check whether a property exists for which this method is the setter (untested):

bool isSetAccessor = invocation.Method.DeclaringType.GetProperties() 
        .Any(prop => prop.GetSetMethod() == invocation.Method)

(Inspiration taken from Marc's answer to a related question.)

Upvotes: 19

mtijn
mtijn

Reputation: 3678

from your MethodInfo object get the MemberType property which should say this is a Property type so you should be able to cast it to PropertyInfo instead. that object exposes the property CanWrite which tells if this is a setter.

Upvotes: -1

usr-local-ΕΨΗΕΛΩΝ
usr-local-ΕΨΗΕΛΩΝ

Reputation: 26904

First, you can examine the MemberType property of MethodInfo class to see if it's a Property.

Now, you should try to guess if it's a get or a set. If you don't want to analyse the name (someone might name a method "set_Something"), then you can check the arguments.

  • If the property accessor accepts one parameter and returns void, it is a set
  • If the property accessor returns one value and doesn't pick parameters, it is a get

You may be interested only in the first check

Upvotes: -1

mao
mao

Reputation: 1404

I think you may try using extension methods: http://msdn.microsoft.com/en-us/library/bb383977.aspx

Upvotes: -4

Related Questions