How to create a Custom Attribute?

5

For some time now I'm trying to understand the concept of custom attribute from C #. I think it kind of looks like Python's decorators system. But I'm not understanding very well.

I gave a codeProject article , but not yet it was clear. I understand that to create a CustomAttribute , you need to create a class that inherits from Attribute . But let's say I want to create a CustomAttribute to validate the int property of a class, to allow only even numbers. In that case where would the validation code be?

An example would be good.

    
asked by anonymous 19.03.2016 / 23:43

1 answer

4

First there is a mistake in thinking that the C # attributes are equivalent to Python's decorators . The operation of both are quite different.

The attribute is just static information. This is a metadata . If they are not called by some mechanism, they do nothing. This call is made via reflection ( example ). So it differs from Python.

Of course you can use this mechanism to make it easy to create a decorator . In fact, this is done in a question in the SO . A direct comparison with Python is done here .

You can create a method in the attribute to perform the validation itself, but it will not be done just because the attribute is present in some element of the code. Your invocation will be somewhere else. Made by the user programmer of the attribute or by some framework that automates this for the final programmer. This answer shows this well .

You have a example of how it works and more thorough in CodeProject. The .Net has an example of how an attribute can be similar (note that IsValid() is not called by itself, like the other methods of the class).

Your example:

[TypeUsage(int)] //atributo hipotético
class EvenAttribute : Attribute {
    public string Message { get; set; }
    public bool IsValid(int value) {
        return value % 2 == 0;
    }
}

This hypothetical attribute TypeUsage that can be used by some tool to ensure that its custom attribute is only used in a property of type int . This attribute would need to be created by you and the scanning tool as well.

Obviously, as shown in the linked examples above, it is possible to do something more sophisticated, it may be something within a larger mechanism, with specific contracts established, it depends on the need, but generally there is the example.

Practical example of use in another question .

    
20.03.2016 / 00:49