First there is a mistake in thinking that the attributes of C# are equivalent to decorators of Python, the operation of both are quite different.
The attribute is just static information, it’s a metadata. If they are not called by some mechanism they do nothing. This call is made through reflection (example), so it differs from Python.
Of course, it is possible to use this mechanism to facilitate the creation of a Decorator. In fact this is done in a question in the OS. One direct comparison with Python is made 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 at some other location, made by the user attribute programmer or by some framework that automates this for the final programmer. That answer shows this well.
Has a example of how it works and one more complete in the Codeproject. The .NET has an example well complete of how it can be a similar attribute (note that the IsValid()
is not called alone, just 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;
}
}
I put in the Github for future reference.
This hypothetical attribute TypeUsage
which can be used by some tool to ensure that your custom attribute is only used in a property of type int
. This attribute would need to be created by you and the checking tool as well.
Obviously, as the examples show linked above, it is possible to do something more sophisticated, it can be something within a larger mechanism, with specific contracts established, it depends on the need, but generally this is the example.
Practical example of use in another question.
My idea was to create something automatic, where I treat in only one place and the effect applies to any created object, leaving the treatment transparent to those who consume the class, ie, any class that "decorates" a property type int with the Attribute
TypeUsage
and when an object of this class is instantiated with a nonpar value, an exception would be thrown. But this should be transparent to the consumer of the class, he should not need to treat. I could use the get and set patterns, but what if I needed the same effect in several other classes, I would have to repeat code.– Matheus Saraiva
My experience is that this does not always work as desired except in simple or flexible systems, unless there are several loopholes, which obviously complicates the mechanism. Automation can be done by a method that deals with this, in general, to be transparent, will be by creating a framework. I guess I shouldn’t have used the
TypeUsage
, you don’t understand his function there, he’s an attribute used in the creation of another attribute. Pretend it doesn’t exist until you understand the rest. Make an exception? Okay, okay, it’s an option, but I probably wouldn’t do this.– Maniero
It may be transparent to the consumer class that uses the attribute, but the call to execute the validation needs to occur somewhere, so it is often used in frameworks that make things kind of "magical" as you want. Maybe you need to think of a more concrete case than you want and ask another question.
– Maniero
No, not what I need is exactly that. I already do this in python through metaclasses. There I have several classes with attributes that cannot be negative. There the treatment is within a metaclass, so all classes that need the treatment make use of the metaclass I created. Thus avoiding code replication. I thought the C# Customattribute feature would allow me to do something similar.
– Matheus Saraiva
A correction, in the first commit I erroneously quoted "Attribute Typeusage" when in fact it is Attibute
EvenAttribute
– Matheus Saraiva
It helps, but not alone. You would need to create the mechanism similar to that of metaclasses on your own or use some framework ready to do it for you.
– Maniero
Do you know me any? Preferably MS
– Matheus Saraiva
It depends on what you need. ASP.Net MVC makes this very automatic.
– Maniero