I have tried lots of times but still I am not able to understand the usage of custom attributes (I have already gone through lots of links).
Can anyone please explain to me a very basic example of a custom attribute with code?
While the code to create a custom Attribute is fairly simple, it's much important that you understand what are attributes:
Attributes are metadata compiled into your program. Attributes themselves doesn't add any functionality to a class, property or module, just data. However, using reflection, one can leverage those attributes in order to create functionality.
So, for instance, let's look at Validation Application Block, from Enterprise Library. If you look at an code example, you'll see:
/// <summary>
/// blah blah code.
/// </summary>
[DataMember]
[StringLengthValidator(8, RangeBoundaryType.Inclusive, 8, RangeBoundaryType.Inclusive, MessageTemplate = "\"{1}\" must always have \"{4}\" characters.")]
public string Code { get; set; }
From the snippet above, one might guess that Code will always be validated, whenever changed, accordingly to the rules of the Validator (in the example, have at least 8 characters and at most 8 characters). But the truth is that the Attribute does nothing, only adds metadata to the property.
However, the Enterprise Library has a Validation.Validate
method that will look into your object, and for each property, it'll check if the contents violates the rule informed by the attribute.
So, that's how you should think about attributes -- a way to add data to your code that might be later used by other methods/classes/etc.
You start by writing a class that derives from Attribute:
public class MyCustomAttribute: Attribute
{
public string SomeProperty { get; set; }
}
Then you could decorate anything (class, method, property, ...) with this attribute:
[MyCustomAttribute(SomeProperty = "foo bar")]
public class Foo
{
}
and finally you would use reflection to fetch it:
var customAttributes = (MyCustomAttribute[])typeof(Foo).GetCustomAttributes(typeof(MyCustomAttribute), true);
if (customAttributes.Length > 0)
{
var myAttribute = customAttributes[0];
string value = myAttribute.SomeProperty;
// TODO: Do something with the value
}
You could limit the target types to which this custom attribute could be applied using the AttributeUsage attribute:
/// <summary>
/// This attribute can only be applied to classes
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class MyCustomAttribute : Attribute
Important things to know about attributes:
- Attributes are metadata.
- They are baked into the assembly at compile-time which has very serious implications of how you could set their properties. Only constant (known at compile time) values are accepted
- The only way to make any sense and usage of custom attributes is to use Reflection. So if you don't use reflection at runtime to fetch them and decorate something with a custom attribute don't expect much to happen.
- The time of creation of the attributes is non-deterministic. They are instantiated by the CLR and you have absolutely no control over it.
Utilizing/Copying Darin Dimitrov's great response, this is how to access a custom attribute on a property and not a class:
The decorated property [of class Foo
]:
[MyCustomAttribute(SomeProperty = "This is a custom property")]
public string MyProperty { get; set; }
Fetching it:
PropertyInfo propertyInfo = typeof(Foo).GetProperty(propertyToCheck);
object[] attribute = propertyInfo.GetCustomAttributes(typeof(MyCustomAttribute), true);
if (attribute.Length > 0)
{
MyCustomAttribute myAttribute = (MyCustomAttribute)attribute[0];
string propertyValue = myAttribute.SomeProperty;
}
You can throw this in a loop and use reflection to access this custom attribute on each property of class Foo
, as well:
foreach (PropertyInfo propertyInfo in Foo.GetType().GetProperties())
{
string propertyName = propertyInfo.Name;
object[] attribute = propertyInfo.GetCustomAttributes(typeof(MyCustomAttribute), true);
// Just in case you have a property without this annotation
if (attribute.Length > 0)
{
MyCustomAttribute myAttribute = (MyCustomAttribute)attribute[0];
string propertyValue = myAttribute.SomeProperty;
// TODO: whatever you need with this propertyValue
}
}
Major thanks to you, Darin!!
来源:https://stackoverflow.com/questions/4879521/how-to-create-a-custom-attribute-in-c-sharp