Can anyone please explain to me a very basic example of a custom attribute with code?
4 Answers
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.

- 45,029
- 5
- 38
- 50

- 1,023,142
- 271
- 3,287
- 2,928
-
3Where, in which function/class, shall I ` use reflection to fetch it` – Hasan A Yousef Oct 17 '16 at 13:25
-
@Hasan A Yousef , for example in Entity Framework there is " Key " attribute that say to framework : This property should be concidered as Primary Key. In creating ORM , attributes are very helpfull – Parsa Mar 26 '17 at 19:24
-
1How do you access a custom attribute on a property and not a class? – Canvas May 24 '17 at 09:29
-
https://learn.microsoft.com/en-us/dotnet/standard/attributes/writing-custom-attributes just for completeness, this msdn page summarizes it very well – Barış Akkurt Feb 12 '19 at 13:26
-
With generics, it's much, much easier to get the types: `var value = typeof(Foo).GetCustomAttributes
().First().SomeProperty;` – jpaugh Apr 25 '19 at 15:55
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.

- 83
- 11

- 8,226
- 7
- 45
- 90
-
will i really like the answer and specially ",one more question i can put same condition in set statement of the above code so how it different from attributs, – slash shogdhe Feb 02 '11 at 20:58
-
1@slash: Can you rephrase that? I didn't quite understood the question. – Bruno Brant Feb 14 '11 at 21:17
-
1I think slash meant to ask about the difference between using attributes and putting the actual validation code inside the property setter. Answer: While writing code inside the setter can be done to validate the value, using attributes alone will not perform validation as such. Attributes are just "meta-data". Another code somewhere else should be interested in the attributes you use, read them, and perform actions based on them. A typical example is a validation library, as @BrunoBrant mentioned. – romar May 10 '13 at 18:26
-
17Not sure why this is the accepted answer. The actual question (which is indexed in Google, as well) is "How to *create* a custom attribute in C#". The answers does not at all delve into that topic. The 2nd answer does, on the other hand. – Drakestar Jul 16 '17 at 22:35
-
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!!
-
how would we extend this if we don't know what types of attributes exist on a property ? `object[] attribute = propertyInfo.GetCustomAttributes(typeof(???), true);` I just want to iterate over all of them and call a method `m1()` of each unknown attribute – heyNow May 02 '19 at 14:12
-
Great question! This is precisely why abstractions and interfaces are a thing. In this case, you could assign an interface which has the method m1() defined. That would inform the compiler that these types hold to the m1() contract, and that this method is available to be called. – PaulG Feb 16 '22 at 21:19
The short answer is for creating an attribute in c# you only need to inherit it from Attribute class, Just this :)
But here I'm going to explain attributes in detail:
basically attributes are classes that we can use them for applying our logic to assemblies, classes, methods, properties, fields, ...
In .Net, Microsoft has provided some predefined Attributes like Obsolete or Validation Attributes like ( [Required], [StringLength(100)], [Range(0, 999.99)]), also we have kind of attributes like ActionFilters in asp.net that can be very useful for applying our desired logic to our codes (read this article about action filters if you are passionate to learn it)
one another point, you can apply a kind of configuration on your attribute via AttibuteUsage.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)]
When you decorate an attribute class with AttributeUsage you can tell to c# compiler where I'm going to use this attribute: I'm going to use this on classes, on assemblies on properties or on ... and my attribute is allowed to use several times on defined targets(classes, assemblies, properties,...) or not?!
After this definition about attributes I'm going to show you an example: Imagine we want to define a new lesson in university and we want to allow just admins and masters in our university to define a new Lesson, Ok?
namespace ConsoleApp1
{
/// <summary>
/// All Roles in our scenario
/// </summary>
public enum UniversityRoles
{
Admin,
Master,
Employee,
Student
}
/// <summary>
/// This attribute will check the Max Length of Properties/fields
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)]
public class ValidRoleForAccess : Attribute
{
public ValidRoleForAccess(UniversityRoles role)
{
Role = role;
}
public UniversityRoles Role { get; private set; }
}
/// <summary>
/// we suppose that just admins and masters can define new Lesson
/// </summary>
[ValidRoleForAccess(UniversityRoles.Admin)]
[ValidRoleForAccess(UniversityRoles.Master)]
public class Lesson
{
public Lesson(int id, string name, DateTime startTime, User owner)
{
var lessType = typeof(Lesson);
var validRolesForAccesses = lessType.GetCustomAttributes<ValidRoleForAccess>();
if (validRolesForAccesses.All(x => x.Role.ToString() != owner.GetType().Name))
{
throw new Exception("You are not Allowed to define a new lesson");
}
Id = id;
Name = name;
StartTime = startTime;
Owner = owner;
}
public int Id { get; private set; }
public string Name { get; private set; }
public DateTime StartTime { get; private set; }
/// <summary>
/// Owner is some one who define the lesson in university website
/// </summary>
public User Owner { get; private set; }
}
public abstract class User
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
}
public class Master : User
{
public DateTime HireDate { get; set; }
public Decimal Salary { get; set; }
public string Department { get; set; }
}
public class Student : User
{
public float GPA { get; set; }
}
class Program
{
static void Main(string[] args)
{
#region exampl1
var master = new Master()
{
Name = "Hamid Hasani",
Id = 1,
DateOfBirth = new DateTime(1994, 8, 15),
Department = "Computer Engineering",
HireDate = new DateTime(2018, 1, 1),
Salary = 10000
};
var math = new Lesson(1, "Math", DateTime.Today, master);
#endregion
#region exampl2
var student = new Student()
{
Name = "Hamid Hasani",
Id = 1,
DateOfBirth = new DateTime(1994, 8, 15),
GPA = 16
};
var literature = new Lesson(2, "literature", DateTime.Now.AddDays(7), student);
#endregion
ReadLine();
}
}
}
In the real world of programming maybe we don't use this approach for using attributes and I said this because of its educational point in using attributes

- 761
- 7
- 18