What are attributes in .NET?
Metadata. Data about your objects/methods/properties.
For example I might declare an Attribute called: DisplayOrder so I can easily control in what order properties should appear in the UI. I could then append it to a class and write some GUI components that extract the attributes and order the UI elements appropriately.
public class DisplayWrapper
{
private UnderlyingClass underlyingObject;
public DisplayWrapper(UnderlyingClass u)
{
underlyingObject = u;
}
[DisplayOrder(1)]
public int SomeInt
{
get
{
return underlyingObject .SomeInt;
}
}
[DisplayOrder(2)]
public DateTime SomeDate
{
get
{
return underlyingObject .SomeDate;
}
}
}
Thereby ensuring that SomeInt is always displayed before SomeDate when working with my custom GUI components.
However, you'll see them most commonly used outside of the direct coding environment. For example the Windows Designer uses them extensively so it knows how to deal with custom made objects. Using the BrowsableAttribute like so:
[Browsable(false)]
public SomeCustomType DontShowThisInTheDesigner
{
get{/*do something*/}
}
Tells the designer not to list this in the available properties in the Properties window at design time for example.
You could also use them for code-generation, pre-compile operations (such as Post-Sharp) or run-time operations such as Reflection.Emit.
For example, you could write a bit of code for profiling that transparently wrapped every single call your code makes and times it. You could "opt-out" of the timing via an attribute that you place on particular methods.
public void SomeProfilingMethod(MethodInfo targetMethod, object target, params object[] args)
{
bool time = true;
foreach (Attribute a in target.GetCustomAttributes())
{
if (a.GetType() is NoTimingAttribute)
{
time = false;
break;
}
}
if (time)
{
StopWatch stopWatch = new StopWatch();
stopWatch.Start();
targetMethod.Invoke(target, args);
stopWatch.Stop();
HandleTimingOutput(targetMethod, stopWatch.Duration);
}
else
{
targetMethod.Invoke(target, args);
}
}
Declaring them is easy, just make a class that inherits from Attribute.
public class DisplayOrderAttribute : Attribute
{
private int order;
public DisplayOrderAttribute(int order)
{
this.order = order;
}
public int Order
{
get { return order; }
}
}
And remember that when you use the attribute you can omit the suffix "attribute" the compiler will add that for you.
NOTE: Attributes don't do anything by themselves - there needs to be some other code that uses them. Sometimes that code has been written for you but sometimes you have to write it yourself. For example, the C# compiler cares about some and certain frameworks frameworks use some (e.g. NUnit looks for [TestFixture] on a class and [Test] on a test method when loading an assembly).
So when creating your own custom attribute be aware that it will not impact the behaviour of your code at all. You'll need to write the other part that checks attributes (via reflection) and act on them.
What Attributes really are?
They are simply metadata stored in the underlying definition (not instance) of the type. For example, if I do:
[Description("some text")]
public string Name {get;set;}
then the fact that DescriptionAttribute
with a description
constructor-parameter of "some text"
is stored in the IL against the property Name
. This has no impact on the cost of each instance, and it does nothing by itself. The only time this data is used is if code explicitly asks the runtime something like:
- "what additional attribute metadata do you have against
Name
?" - "does
Name
have aDescriptionAttribute
?" - "please construct me the
DescriptionAttribute
stored againstName
, if one"
and then does something with the result.
CAVEAT: there are some attributes that are processed differently by the compiler and/or CLI, and are implemented differently. [Serializable]
, for example, becomes an IL type flag - not an IL attribute - but the runtime shims it so that the APIs report it as though it were the other.
Custom vs. non-custom attributes?
I don't know if the following has any relevance, but if you say
var a = typeof(string).Attributes;
you get a value of a flags enum type called TypeAttributes
. Maybe these flags are the "non-custom" attributes of the type?
Is .Net attribute feature used at compile-time or run-time or both?
Attributes are output as metadata to the assembly at compile time. This meta data is then used at runtime via reflection - for example using GetCustomAttributes()
.
Some attributes are used by the compiler at compile time, too. For example the compiler looks at the AttributeUsageAttribute
to determine if an attribute can be used for a specific object.
Related Topics
Where to Learn About VS Debugger 'Magic Names'
Do Try/Catch Blocks Hurt Performance When Exceptions Are Not Thrown
Make Https Call Using Httpclient
How to Stop C# Console Applications from Closing Automatically
Can Anonymous Class Implement Interface
How to Calculate Distance Similarity Measure of Given 2 Strings
Assigning Out/Ref Parameters in Moq
How to Load Dll 'Sqlite.Interop.Dll'
How to Configure Socket Connect Timeout
How to Change the Timeout on a .Net Webclient Object
Split String Containing Command-Line Parameters into String[] in C#
Xml Serialization - Hide Null Values
Return File in ASP.NET Core Web API
ASP.NET MVC: How to Display a Byte Array Image from Model
{"<User Xmlns=''> Was Not Expected.} Deserializing Twitter Xml