You can add metadata (structured descriptions which are embedded in your C# code, and meant to be used by other programs reflecting on your code) into your .NET code using the facility called "Attributes."
Attributes in .NET are written inside brackets [] and precede the definition of Classes, Interfaces, Structs, Properties, etc. Attributes
declare a relationship.
.NET has many predefined Attributes you may have already seen being used in your code, and which you can use yourself. For example, in a WinForms Program.cs file, you'll see [STAThread] which is an Attribute.
This is an excellent resource for getting familiar with .NET's predefined Attributes: [
^].
You create you own Attributes by creating sealed Public Classes that inherit from System.Attribute:
public sealed class MyAttribute : System.Attribute {}
Later versions of Visual Studio and .NET will automatically insert an Attribute Template for you:
1. Position the text insert cursor in a Visual Studio C# code-edit windows on the line just before, for example, a Class definition
2. Type in the word Attribute, then press the Tab key twice: this should appear (the example shown here is generated by .NET 4.5, VS Studio 2012):
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
sealed class MyAttribute : Attribute
{
readonly string positionalString;
public MyAttribute(string positionalString)
{
this.positionalString = positionalString;
throw new NotImplementedException();
}
public string PositionalString
{
get { return positionalString; }
}
public int NamedInt { get; set; }
}
Once you have defined an Attribute Class, you then "decorate" those Objects in your code that you wish to later be identified as being "bound" to the Attribute with the Attribute name inside brackets.
There is also a syntax for passing data in the Attribute definition you use on your Classes and other Objects. You see examples of that in the code shown above: 'NamedInt is a "named" variable, and 'positionalString is a "positional" variable: positional variables are required parameters passed to the Attribute Constructor, and named variables are, of course, not required.
I suggest you start reading some of the tutorials on using Attributes here on CodeProject: [
^] to get a sense of what you can do with custom Attributes.
You can go "very deep" with Attributes if you wish: the AttributeUsage facility is almost a kind of meta-Attribute that lets you manipulate what objects an Attribute can be applied to (AttributeTargets).
You could actually create Attributes at run-time using Reflection.Emit and wire-them-up to Classes you've built on-the-fly (I have yet to see a useful example of that).