How to use method parameter attributes

Ross picture Ross · Jun 17, 2013 · Viewed 24.1k times · Source

I've been struggling to find examples of how to write a custom attribute to validate method parameters, i.e., turn this form:

public void DoSomething(Client client)
{
    if (client.HasAction("do_something"))
    {
        // ...
    }
    else
    {
        throw new RequiredActionException(client, "do_something");
    }
}

into this:

public void DoSomething([RequiredAction(Action="some_action")] Client client)
{
    // ...
}

As far as I can tell, I need to add this attribute to my custom attribute, but I'm at a loss on how to access the decorated parameter Client:

[AttributeUsageAttribute(AttributeTargets.Parameter)]
public class RequireActionAttribute : System.Attribute
{
    public Type Action {get; set;}

    public RequireActionAttribute()
    {
        // .. How do you access the decorated parameter?
        Client client = ???

        if (!client.HasAction(Action))
        {
            throw new RequiredActionException(client, Action);
        }
    }
}

Answer

Jon Skeet picture Jon Skeet · Jun 17, 2013

You're applying it correctly - but an attribute basically doesn't know the member it refers to. This definitely makes life harder.

Not only does it not have access to the member that it refers to, but that member would be a ParameterInfo, not a Client - there's no easy way of accessing the value of a parameter externally. Your method would need to call some helper code, passing the value of client in order to handle it appropriately... or you need to hook into the code which is going to call your method to start with, in order to notice the attribute.

It's not clear exactly how you were hoping to use this, but it may well be that you need to change your design significantly.