How to create a custom attribute in C#
While the code to create a custom Attribute is fairly simple, it's very important that you understand what attributes are:
Attributes are metadata compiled into your program. Attributes themselves do not 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 the Validation Application Block, from Microsoft's Enterprise Library. If you look at a 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 the 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; as mentioned previously, it 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 violate 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.
create custom attribute for class property
This how to access the attributes using Reflection
:
(Sure you need to move that to some helper class or something).
static bool Validate<T>(T obj)
{
var properties = obj.GetType().GetProperties().ToList();
foreach(var prop in properties)
{
if(prop.IsDefined(typeof(RequiredAttribute)))
{
object value = prop.GetValue(obj);
if(value == null)
{
// do something
}
}
if(prop.IsDefined(typeof(ContainsNumericAttribute)))
{
}
}
return false; // dummy value now
}
Usage:
MyClass cc = new MyClass()
{
cost = 5
};
Validate(cc); // false, id required
If you want , you can create a validation results object and return it from Validate
method add all validations that fails to that object.
C# Custom Attribute parameters
The accepted answer uses the public property instead of a private field. The benefit of public property is you can omit the constructor and supply the values of the properties in the default constructor.
I change your first code, the one with public property, to something like this.
class MyCustomAttribute : Attribute {
public int[] Values { get; set; }
}
[MyCustomAttribute(Values = new int[] { 3, 4, 5 })]
class MyClass { }
Related Topics
Entity Framework (.Net Full Framework) Ordering Includes
Replace Parameter in Lambda Expression
How to Fix Error: "Could Not Find Schema Information for the Attribute/Element" by Creating Schema
ASP.NET Core 2.0 Ldap Active Directory Authentication
Return JSON with Error Status Code MVC
Unhandled Exceptions in Backgroundworker
How to Read Command Line Arguments of Another Process in C#
Custom Attribute on Property - Getting Type and Value of Attributed Property
Grab All Text from HTML with HTML Agility Pack
Getting a System.Type from Type's Partial Name
Async Network Operations Never Finish
C# Pattern to Prevent an Event Handler Hooked Twice
Generating Xml File Using Xsd File
Get the Property, as a String, from an Expression<Func<Tmodel,Tproperty>>
Waiting for Async/Await Inside a Task
How to Render a Wpf Usercontrol to a Bitmap Without Creating a Window