Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use method parameter attributes

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);
        }
    }
}
like image 952
Ross Avatar asked Jun 17 '13 14:06

Ross


People also ask

What is parameter attribute in C#?

The types of positional and named parameters for an attribute class are limited to the attribute parameter types, which are: One of the following types: bool , byte , char , double , float , int , long , sbyte , short , string , uint , ulong , ushort . The type object . The type System.

What are attributes and parameters?

Attribute vs Parameter An attribute is a variable of any type that is declared directly in a class. A parameter is a variable defined by the function that receives a value when it is called. An attribute is used with classes and objects. A parameter is used with a function or a method.

What is a method parameter modifier?

ref (reference) parameter: If a parameter is attached with a ref modifier, then changes will be made in a method that affect the calling method. This is also known as call-by-reference.

How would you determine if a class has a particular attribute?

The same you would normally check for an attribute on a class. Here's some sample code. typeof(ScheduleController) . IsDefined(typeof(SubControllerActionToViewDataAttribute), false);


3 Answers

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.

like image 178
Jon Skeet Avatar answered Oct 05 '22 08:10

Jon Skeet


Attributes are not enough for doing it.

If I understood you correctly you want to add an attribute on a parameter in order to validate it at run time and that is impossible only with attributes.

It is impossible because attributes are only "metadata" and not executed code.

You will need some "real" code to read it and act accordingly. That code can be injected at compile time or you can hook into the function execution.

like image 32
silver Avatar answered Oct 05 '22 10:10

silver


Attributes probably should be put on the method itself. When I was searching for the solution I found the following link and the way it uses interceptor seems even better http://www.codinginstinct.com/2008/05/argument-validation-using-attributes.html

like image 30
Tony Avatar answered Oct 05 '22 10:10

Tony