According to a book I'm reading, the AllowMultiple public property of AttributeUsage specifies:
...whether the target can have multiple instances of the attribute applied to it.
Why would I want/not want to use this?
Attributes are meta-data. Typically, you'll want to decorate a member or type with an Attribute in order to track some information about it.
For example, the DescriptionAttribute is used by the PropertyGrid to label a description of a property:
[Description("This is my property")]
public int MyProperty { get; set; }
Most of the time, having more than one description would not make sense.
However, it is possible that a specific attribute makes sense to use more than once. In that case, you'd want to set the Attribute to allow multiple instances of itself tagged to the same attribute.
(Not that I'd do this, but...) Say you made a custom attribute to track major changes to a class. You might want to list this for every major change:
[Changes(Version=1.1, Change="Added Foo Feature")]
[Changes(Version=2.0, Change="Added Bar Feature")]
public class MyClass
{
// ...
This example might be a little contrived but hopefully it gets the point across.
[Convertable(typeof(Int32)), Convertable(typeof(Double))]
public class Test
{
}
This depends what the attributes are.
For example, you could make an attribute that marks a class as depending on something, and you could allow multiple dependencies.
For a concrete example, look at SuppressMessage, which suppresses a code analysis warning. A member can have multiple warnings that you might want to suppress.
Another example is WebResource; an assembly can contain multiple resources.
No contrived example here, I used it in real production code. I wrote some code to parse a file containing pairs of data like (code=value). I put a custom attribute on a function to indicate it should be called for a given code.
[CanParseCode("G1")]
[CanParseCode("G2")]
private void ParseGXCodes(string code, string value)
{
...
}
This particular format is a somewhat old and domain specific with hundreds of different codes. My goal was to write a framework to make it easier to write file processors that could extract only the codes it needs and ignore the rest. Allowing the same attribute multiple times made it easy to express the intent of the code by simply declaring attributes on the function(s) that process each code.
Real World Application of Attribute AllowMultiple=true usefulness
[ManagesType(typeof(SPEC_SEC_OC), true)]
[ManagesType(typeof(SPEC_SEC_04_OC), true)]
public class LibSpecSelectionView : CustomView
{
public LibSpecSelectionView(SPEC_SEC_OC)
{}
public LibSpecSelectionView(SPEC_SEC_O4_OC)
{}
....
}
public static class ViewManager
{
... static Dictionary of views built via reflection
public void LaunchView(this CollectionBaseClass cbc)
{
... Find class registered to handle cbc type in dictionary and call ctor
}
}
SPEC_SEC_OC myOC = DataClient.Instance.GetSPEC_SEC_OC();
myOC.LaunchView()
I flipped AllowMultiple=true earlier today to allow for the ManagesType attribute to be used more than once. We have several hundred Custom Collection Classes. Most of these custom collections have a view that inherits from CustomView designed to handle creation of a UI view for a specific type of custom collection and presenting it to the user. The ManagesType attribute is used via reflection to build a dictionary of EVERY View in our app that inherits from CustomView to "register" what object type it was designed to handle. The LibSpecSelectionView "broke that pattern" by displaying two different collections at the same time (creates two tabs and shows one custom collection in one tab and the other in the second tab) So the same view is capable of handling two different custom collections.
The dictionary of which views are capable of handling which collection types is then leveraged through an extension method to allow any of our custom collections to launch the registered view (or a default one if there is not a "registered" view) through a one line call to the view manager.
Related
What are attributes in .NET, what are they good for, and how do I create my own attributes?
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.
Many people have answered but no one has mentioned this so far...
Attributes are used heavily with reflection. Reflection is already pretty slow.
It is very worthwhile marking your custom attributes as being sealed classes to improve their runtime performance.
It is also a good idea to consider where it would be appropriate to use place such an attribute, and to attribute your attribute (!) to indicate this via AttributeUsage. The list of available attribute usages might surprise you:
Assembly
Module
Class
Struct
Enum
Constructor
Method
Property
Field
Event
Interface
Parameter
Delegate
ReturnValue
GenericParameter
All
It's also cool that the AttributeUsage attribute is part of the AttributeUsage attribute's signature. Whoa for circular dependencies!
[AttributeUsageAttribute(AttributeTargets.Class, Inherited = true)]
public sealed class AttributeUsageAttribute : Attribute
Attributes are a kind of meta data for tagging classes. This is often used in WinForms for example to hide controls from the toolbar, but can be implemented in your own application to enable instances of different classes to behave in specific ways.
Start by creating an attribute:
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)]
public class SortOrderAttribute : Attribute
{
public int SortOrder { get; set; }
public SortOrderAttribute(int sortOrder)
{
this.SortOrder = sortOrder;
}
}
All attribute classes must have the suffix "Attribute" to be valid.
After this is done, create a class that uses the attribute.
[SortOrder(23)]
public class MyClass
{
public MyClass()
{
}
}
Now you can check a specific class' SortOrderAttribute (if it has one) by doing the following:
public class MyInvestigatorClass
{
public void InvestigateTheAttribute()
{
// Get the type object for the class that is using
// the attribute.
Type type = typeof(MyClass);
// Get all custom attributes for the type.
object[] attributes = type.GetCustomAttributes(
typeof(SortOrderAttribute), true);
// Now let's make sure that we got at least one attribute.
if (attributes != null && attributes.Length > 0)
{
// Get the first attribute in the list of custom attributes
// that is of the type "SortOrderAttribute". This should only
// be one since we said "AllowMultiple=false".
SortOrderAttribute attribute =
attributes[0] as SortOrderAttribute;
// Now we can get the sort order for the class "MyClass".
int sortOrder = attribute.SortOrder;
}
}
}
If you want to read more about this you can always check out MSDN which has a pretty good description.
I hope this helped you out!
An attribute is a class that contains some bit of functionality that you can apply to objects in your code. To create one, create a class that inherits from System.Attribute.
As for what they're good for... there are almost limitless uses for them.
http://www.codeproject.com/KB/cs/dotnetattributes.aspx
Attributes are like metadata applied to classes, methods or assemblies.
They are good for any number of things (debugger visualization, marking things as obsolete, marking things as serializable, the list is endless).
Creating your own custom ones is easy as pie. Start here:
http://msdn.microsoft.com/en-us/library/sw480ze8(VS.71).aspx
In the project I'm currently working on, there is a set of UI objects of various flavours and an editor to assembly these objects to create pages for use in the main application, a bit like the form designer in DevStudio. These objects exist in their own assembly and each object is a class derived from UserControl and has a custom attribute. This attribute is defined like this:
[AttributeUsage (AttributeTargets::Class)]
public ref class ControlDescriptionAttribute : Attribute
{
public:
ControlDescriptionAttribute (String ^name, String ^description) :
_name (name),
_description (description)
{
}
property String ^Name
{
String ^get () { return _name; }
}
property String ^Description
{
String ^get () { return _description; }
}
private:
String
^ _name,
^ _description;
};
and I apply it to a class like this:
[ControlDescription ("Pie Chart", "Displays a pie chart")]
public ref class PieControl sealed : UserControl
{
// stuff
};
which is what the previous posters have said.
To use the attribute, the editor has a Generic::List <Type> containing the control types. There is a list box which the user can drag from and drop onto the page to create an instance of the control. To populate the list box, I get the ControlDescriptionAttribute for the control and fill out an entry in the list:
// done for each control type
array <Object ^>
// get all the custom attributes
^attributes = controltype->GetCustomAttributes (true);
Type
// this is the one we're interested in
^attributetype = ECMMainPageDisplay::ControlDescriptionAttribute::typeid;
// iterate over the custom attributes
for each (Object ^attribute in attributes)
{
if (attributetype->IsInstanceOfType (attribute))
{
ECMMainPageDisplay::ControlDescriptionAttribute
^description = safe_cast <ECMMainPageDisplay::ControlDescriptionAttribute ^> (attribute);
// get the name and description and create an entry in the list
ListViewItem
^item = gcnew ListViewItem (description->Name);
item->Tag = controltype->Name;
item->SubItems->Add (description->Description);
mcontrols->Items->Add (item);
break;
}
}
Note: the above is C++/CLI but it's not difficult to convert to C#
(yeah, I know, C++/CLI is an abomination but it's what I have to work with :-( )
You can put attributes on most things and there are whole range of predefined attributes. The editor mentioned above also looks for custom attributes on properties that describe the property and how to edit it.
Once you get the whole idea, you'll wonder how you ever lived without them.
As said, Attributes are relatively easy to create. The other part of the work is creating code that uses it. In most cases you will use reflection at runtime to alter behavior based on the presence of an attribute or its properties. There are also scenarios where you will inspect attributes on compiled code to do some sort of static analysis. For example, parameters might be marked as non-null and the analysis tool can use this as a hint.
Using the attributes and knowing the appropriate scenarios for their use is the bulk of the work.
Attributes are, essentially, bits of data you want to attach to your types (classes, methods, events, enums, etc.)
The idea is that at run time some other type/framework/tool will query your type for the information in the attribute and act upon it.
So, for example, Visual Studio can query the attributes on a 3rd party control to figure out which properties of the control should appear in the Properties pane at design time.
Attributes can also be used in Aspect Oriented Programming to inject/manipulate objects at run time based on the attributes that decorate them and add validation, logging, etc. to the objects without affecting the business logic of the object.
You can use custom attributes as a simple way to define tag values in sub classes without having to write the same code over and over again for each subclass. I came across a nice concise example by John Waters of how to define and use custom attributes in your own code.
There is a tutorial at http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx
To get started creating an attribute, open a C# source file, type attribute and hit [TAB]. It will expand to a template for a new attribute.
Attributes are also commonly used for Aspect Oriented Programming. For an example of this check out the PostSharp project.
In a C# (visual Studio 2010) project, I have a class with large number of properties, and I populate objects of this class with data and add to list object to pass it to display list of items (Something like results of a search).
My problem is there I don't need all the properties of the class to display the above list, so do I have to create another class only with required field to display the (results) list? Is it correct according to the OOP concepts?
Your properties object can implement multiple interfaces, as requested by different parts of your program.
If you define these interfaces:
public interface IBasicInfo
{
string Name { get; }
string Id { get; }
}
internal interface IFullInfo : IBasicInfo
{
string Address { get; }
}
internal interface IInternalStuff
{
Stuff Data { get; }
}
And your properties class implements them like this:
internal class Properties : IFullInfo, IInternalStuff
{
// some basic implementation
}
Then you can pass this class to a different part of your app which has a method like this:
public void Display(IBasicInfo info)
{
...
}
And the calling code will only see properties which belong to IBasicInfo. Note that only IBasicInfo needs to be public, and even the Properties class is internal to ensure that no calling code can cast back to the actual implementation and mess with it.
Alternatively, if your calling code contains completely different interfaces, then it is perfectly reasonable to convert them into Data Transfer Objects, and even modify their contents to match caller's expectations (adapter pattern). There are tools which automate this task (Automapper, for example).
I think yes, it is called Data transfer object
You might consider using a solution like automapper to map from a class that has N number of properties to another that has M number of properties. It relies on some conventional information (same/similar name) but can be tweaked too.
This is a pretty standard way of taking model data pulled from a DB and converting it into something that can be displayed on a view in webpage. I build a "viewmodel" that just has the stuff I want to display, which is typically a subset of the fields, and then map between them. Something like automapper makes it pretty easy to do so.
Since you have a reference type (a class), it shouldn't be costly to pass the original object rather than a new object containing a subset of the data.
If you want to protect the object from being manipulated by the recipient of the list, then you could define a read-only interface for the class, and pass it as that.
I have a control circuit which has multiple settings and may have any number of sensors attached to it (each with it's own set of settings). These sensors may only be used with the control circuit. I thought of using nested classes like so:
public class ControlCircuitLib
{
// Fields.
private Settings controllerSettings;
private List<Sensor> attachedSensors;
// Properties.
public Settings ControllerSettings
{ get { return this.controllerSettings; } }
public List<Sensor> AttachedSensors
{ get { return this.attachedSensors; } }
// Constructors, methods, etc.
...
// Nested classes.
public class Settings
{
// Fields.
private ControlCircuitLib controllerCircuit;
private SerialPort controllerSerialPort;
private int activeOutputs;
... (many, many more settings)
// Properties.
public int ActiveOutputs
{ get { return this.activeOutputs; } }
... (the other Get properties for the settings)
// Methods.
... (method to set the circuit properties though serial port)
}
public class Sensor
{
// Enumerations.
public enum MeasurementTypes { Displacement, Velocity, Acceleration };
// Fields.
private ControlCircuitLib controllerCircuit;
private string sensorName;
private MeasurementTypes measurementType;
private double requiredInputVoltage;
... (many, many more settings)
// Properties.
public string SensorName {...}
... (Get properties)
// Methods.
... (methods to set the sensor settings while attached to the control circuit)
}
}
I have read that public nested classes are a "no-no" but that there are exceptions. Is this structure OK or is there a better option?
Thanks!
EDIT
Below is a crude hierarchy of the control circuit for which I am trying to write a library class for; I used code formatting to prevent text-wrap.
Control Circuit (com. via serial port) -> Attached Sensors (up to 10) -> Sensor Settings (approx. 10 settings per sensor)
Basic Controller Settings (approx. 20 settings)
Output Settings (approx. 30 settings)
Common Settings (approx. 30 settings)
Environment Settings (approx. 10 settings)
All of the settings are set through the controller but I would like an organized library instead of just cramming all ~100 methods, properties, and settings under one Controller class. It would be HUGELY appreciated if someone could offer a short example outlining the structure they would use. Thanks!
The contents of a class should be the implementation details of that class. Are the nested classes implementation details of the outer class, or are you merely using the outer class as a convenient name scoping and discovery mechanism?
If the former, then you shouldn't be making the private implementation details publically available. Make them private if they are implementation details of the class.
If the latter, then you should be using namespaces, not outer classes, as your scoping and discovery mechanism.
Either way, public nested classes are a bad code smell. I'd want to have a very good reason to expose a nested class.
I don't have too much problem with public nested classes (I'm not a fan of dogmatic rules, in general) but have you considered putting all of these types in their own namespace instead? That's the more common way of grouping classes together.
EDIT: Just to clarify, I would very rarely use public nested classes, and I probably wouldn't use them here, but I wouldn't completely balk at them either. There are plenty of examples of public nested types in the framework (e.g. List<T>.Enumerator) - no doubt in each case the designers considered the "smell" of using a nested class, and considered it to be less of a smell than promoting the type to be a top-level one, or creating a new namespace for the types involved.
From your comment to Eric's answer:
These sensors can ONLY be used with a specific circuit
This kind of relationship is commonly known as a dependency. The Sensor constructor should take a ControlCircuit as a parameter. Nested classes do not convey this relationship.
and you can't get/set any sensor settings without going through the controller circuit;
I think that means that all Sensor properties will delegate to (call) or somehow inform (fire an event on) the ControlCircuit when they're used. Or, you'd have some kind of internal interface to the sensor that only the control circuit uses, making Sensor an opaque class to the outside world. If that's the case, Sensor is just an implementation detail and could be nested private or internal (there's also no need to "save" a sensor instance if you can't do anything with it).
Also, I don't even want to expose a Sensor constructor (the controller will have a method for this)
The fact that the Sensor constructor now takes a control circuit is enough of a hint as to what depends on what that you could leave the constructor public. You can also make it internal.
A general comment that I have is that this design is very coupled. Maybe if you had some interfaces between control circuit, sensor and settings, it would be easier to understand each component independently, and the design would be more testable. I always find beneficial to make the roles that each component plays explicit. That is, if they're not just implementation details.
I would say the better option is moving those nested classes out of the class they're in and have them stand on their own. Unless I'm missing something you appear only to have them in the main class in order for some sort of scoping concept, but really, that's what namespaces are for.
I generally disagree with Eric on this.
The thing I usually consider is: how often should the end user use the type name ControlCircuitLib.Sensor. If it's "almost never, but the type needs to be public so that doing something is possible", then go for inner types. For anything else, use a separate type.
For example,
public class Frobber {
public readonly FrobType Standard = ...;
public readonly FrobType Advanced = ...;
public void Frob(FrobType type) { ... }
public class FrobType { ... }
}
In this example, the FrobType only acts as an opaque 'thing'. Only Frobber needs to know what it actually is, although it needs to be possible to pass it around outside that class. However, this sort of example is quite rare; more often than not, you should prefer to avoid nested public classes.
One of the most important things when designing a library is to keep it simple. So use whichever way makes the library and the using code simpler.
I like nested classes in cases like this because it shows the relationship. If you do not want users of the outer class to be able to create items of the inner class separately from the outer class, you can always hide the constructors and use factory methods in the outer class to create elements of the inner class. I use this structure a lot.
This structure seems completely reasonable to me. I wasn't aware until today that Microsoft has advised against doing this, but I'm still not aware why they've advised as such.
I've used this structure in a situation where the nested class only exists to support the containing class (i.e. it's part of its implementation), but other classes need to be able to see it in order to interact with the containing class (i.e. it's part of the class's API).
That being said, Eric generally knows what he's talking about, so out of respect for his knowledge and for the time being, I've converted those classes to use namespaces instead.
Currently, I'm not liking the results. I have a class named BasicColumn, which exists only to represent a column in a class called Grid. Previously, that class was always addressed as Grid.BasicColumn, which was great. That's exactly how I want it to be referred to. Now, with the Grid and the BasicColumn both in the Grids namespace, it's just referred to as BasicColumn with a 'using Grids' at the top of the file. There's nothing to indicate its special relationship with Grid, unless I want to type out the entire namespace (which has a few prefixes before Grid I've left out for simplicity).
If anyone can point out an actual reason why using public nested classes is somehow counterproductive or suboptimal, other than the irrelevant fact that Microsoft doesn't intend for them to be used that way, then I'd love to hear it.
While I feel Eric's answer is correct, it is important to realize it doesn't really fully address what your situation is.
Your case sounds very similar to one I frequently find myself in where you have a class which is really implementation details of another class, however, some details or functionality of that sub-component naturally lend themselves towards being exposed directly for some minor aspects that are not governed by the parent.
In these cases, what you can do is use interfaces. The nested classes need not be public as they really are internal details of the class they are nested within, but a subset of functionality (an interface) needs to be made publicly available and can be implemented by the class.
This allows for construction of the internal structures to be controlled by the class they are nested within while still allowing direct access to the type from a namespace for external references. (The caller will use SomeNamespace.IChildApi as the name rather than SomeNamespace.NestingClass.NestedClass.SecondNestedClass.ThirdNestedClass, etc.)
My searches keep turning up only guides explaining how to use and apply attributes to a class. I want to learn how to create my own attribute classes and the mechanics of how they work.
How are attribute classes instantiated? Are they instantiated when the class they are applied to is instantiated? Is one instantiated for each class instantiated that it is applied to? E.g. if I apply the SerializableAttribute class to a MyData class, and I instantiate 5 MyData instances, will there be 5 instances of the SerializbleAttribute class created behind the scenes? Or is there just one instance shared between all of them?
How do attribute class instances access the class they are associated with? How does a SerializableAttribute class access the class it is applied to so that it can serialize it's data? Does it have some sort of SerializableAttribute.ThisIsTheInstanceIAmAppliedTo property? :) Or does it work in the reverse direction that whenever I serialize something, the Serialize function I pass the MyClass instance to will reflectively go through the Attributes and find the SerialiableAttribute instance?
I haven't use attributes in my day-to-day work before, but I have read about them.
Also I have done some tests, to back up what I'll say here. If I'm wrong in any place - feel free to tell me this :)
From what I know, attributes are not acting as regular classes. They aren't instantiated when you create an object that they are applied to, not one static instance, not 1 per each instance of the object.
Neither do they access the class that they are applied to..
Instead they act like properties (attributes? :P ) of the class. Not like the .NET class properties, more like in the "one property of glass is transparency" kind of property. You can check which attributes are applied to a class from reflection, and then act on it accordingly. They are essentially metadata that is attached to the class definition, not the objects of that type.
You can try to get the list of attributes on a class, method, property, etc etc.. When you get the list of these attributes - this is where they will be instantiated. Then you can act on the data within these attributes.
E.g. the Linq tables, properties have attributes on them that define which table/column they refer to. But these classes don't use these attributes. Instead, the DataContext will check the attributes of these objects when it will convert linq expression trees to SQL code.
Now for some real examples.. I've ran these in LinqPad, so don't worry about the strange Dump() method. I've replaced it with Console.WriteLine to make the code easier to understand for the people who don't know about it :)
void Main()
{
Console.WriteLine("before class constructor");
var test = new TestClass();
Console.WriteLine("after class constructor");
var attrs = Attribute.GetCustomAttributes(test.GetType()).Dump();
foreach(var attr in attrs)
if (attr is TestClassAttribute)
Console.WriteLine(attr.ToString());
}
public class TestClassAttribute : Attribute
{
public TestClassAttribute()
{
DefaultDescription = "hello";
Console.WriteLine("I am here. I'm the attribute constructor!");
}
public String CustomDescription {get;set;}
public String DefaultDescription{get;set;}
public override String ToString()
{
return String.Format("Custom: {0}; Default: {1}", CustomDescription, DefaultDescription);
}
}
[Serializable]
[TestClass(CustomDescription="custm")]
public class TestClass
{
public int Foo {get;set;}
}
The console result of this method is:
before class constructor
after class constructor
I am here. I'm the attribute constructor!
Custom: custm; Default: hello
And the Attribute.GetCustomAttributes(test.GetType()) returns this array:
(the table shows all available columns for all entries.. So no, the Serializable attribute does not have these properties :) )
Got any more questions? Feel free to ask!
UPD:
I've seen you ask a question: why use them?
As an example I'll tell you about the XML-RPC.NET library.
You create your XML-RPC service class, with methods that will represent the xml-rpc methods. The main thing right now is: in XmlRpc the method names can have some special characters, like dots. So, you can have a flexlabs.ProcessTask() xml rpc method.
You would define this class as follows:
[XmlRpcMethod("flexlabs.ProcessTask")]
public int ProcessTask_MyCustomName_BecauseILikeIt();
This allows me to name the method in the way I like it, while still using the public name as it has to be.
Attributes are essentially meta data that can be attached to various pieces of your code. This meta data can then be interogate and affect the behaviour of certain opperations.
Attributes can be applied to almost every aspect of your code. For example, attributes can be associated at the Assembly level, like the AssemblyVersion and AssemblyFileVersion attributes, which govern the version numbers associated with the assembly.
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Then the Serializable attribute for example can be applied to a type declaration to flag the type as supporting serialization. In fact this attribute has special meaning within the CLR and is actually stored as a special directive directly on the type in the IL, this is optimized to be stored as a bit flag which can be processed much more efficiently, there are a few attributes on this nature, which are known as pseudo custom attributes.
Still other attributes can be applied to methods, properties, fields, enums, return values etc. You can get an idea of the possible targets an attribute can be applied to by looking at this link
http://msdn.microsoft.com/en-us/library/system.attributetargets(VS.90).aspx
Further to this, you can define your own custom attributes which can then be applied to the applicable targets that your attributes are intended for. Then at runtime your code could reflect on the values contained in the custom attributes and take appropriate actions.
For a rather naive example, and this is just for the sake of example :)
You might want to write a persistence engine that will automatically map Classes to tables in your database and map the properties of the Class to table columns. You could start with defining two custom attributes
TableMappingAttribute
ColumnMappingAttribute
Which you can then apply to your classes, as an example we have a Person class
[TableMapping("People")]
public class Person
{
[ColumnMapping("fname")]
public string FirstName {get; set;}
[ColumnMapping("lname")]
public string LastName {get; set;}
}
When this compiles, other than the fact that the compiler emits the additional meta data defined by the custom attributes, little else is impacted. However you can now write a PersistanceManager that can dynamically inspect the attributes of an instance of the Person class and insert the data into the People table, mapping the data in the FirstName property to the fname column and the LastName property to the lname column.
As to your question regarding the instances of the attributes, the instance of the attribute is not created for each instance of your Class. All instances of People will share the same instance of the TableMappingAttribute and ColumnMappingAttributes. In fact, the attribute instances are only created when you actually query for the attributes the first time.
Yes they're instantiated with the parameters you give it.
The attribute does not "access" the class. The attribute is attached to the class' / property's attribute list in the reflection data.
[Serializable]
public class MyFancyClass
{ ... }
// Somewhere Else:
public void function()
{
Type t = typeof(MyFancyClass);
var attributes = t.GetCustomAttributes(true);
if (attributes.Count(p => p is SerializableAttribute) > 0)
{
// This class is serializable, let's do something with it!
}
}
Think of attributes are post-its that are attached to the classes or method definitions (embedded in the assembly metadata).
You can then have a processor/runner/inspector module that accepts these types by reflecting, looks for these post-its and handles them differently. This is called declarative programming. You declare some behavior instead of writing code for them in the type.
Serializable attribute on a type declares that it is built to be serialized. The XmlSerializer can then accept an object of this class and do the needful. You mark the methods that need to be serialized/hidden with the right post-its.
another example would the NUnit. The NUnit runner looks at the [TestFixture] attributes all classes defined in the target assembly to identify test classes. It then looks for methods marked with [Test] attribute to identify the tests, which it then runs and displays the results.
You may want to run through this tutorial at MSDN which has most of your questions answered along with an example at the end. Although they could have extracted a method called
Audit(Type anyType); instead of duplicating that code. The example 'prints information' by inspecting attributes.. but you could do anything in the same vein.
If you take an eye out this downloadable open source code LINQ to Active Directory (CodePlex), you might find interesting the mechanism of the Attributes.cs file where Bart De Smet has written all of his attributes classes definitions. I have learned attributes there.
In short, you may specialize the Attribute class and code some specialized properties for your needs.
public class MyOwnAttributeClass : Attribute {
public MyOwnAttributeClass() {
}
public MyOwnAttributeClass(string myName) {
MyName = myName;
}
public string MyName { get; set; }
}
and then, you may use it wherever MyOwnAttributeClass gets useful. It might either be over a class definition or a property definition.
[MyOwnAttributeClass("MyCustomerName")]
public class Customer {
[MyOwnAttributeClass("MyCustomerNameProperty")]
public string CustomerName { get; set; }
}
Then, you can get it through reflection like so:
Attribute[] attributes = typeof(Customer).GetCustomAttribute(typeof(MyOwnAttributeClass));
Consider that the attribute you put between square brackets is always the constructor of your attribute. So, if you want to have a parameterized attribute, you need to code your constructor as such.
This code is provided as is, and may not compile. Its purpose is to give you an idea on how it works.
Indeed, you generally want to have a different attribute class for a class than for a property.
Hope this helps!
Not much time to give you a fuller answer, but you can find the Attributes that have been applied to a value using Reflection. As for creating them, you inherit from the Attribute Class and work from there - and the values that you supply with an attribute are passed to the Attribute class's constructor.
It's been a while, as you might be able to tell...
Martin
What are attributes in .NET, what are they good for, and how do I create my own attributes?
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.
Many people have answered but no one has mentioned this so far...
Attributes are used heavily with reflection. Reflection is already pretty slow.
It is very worthwhile marking your custom attributes as being sealed classes to improve their runtime performance.
It is also a good idea to consider where it would be appropriate to use place such an attribute, and to attribute your attribute (!) to indicate this via AttributeUsage. The list of available attribute usages might surprise you:
Assembly
Module
Class
Struct
Enum
Constructor
Method
Property
Field
Event
Interface
Parameter
Delegate
ReturnValue
GenericParameter
All
It's also cool that the AttributeUsage attribute is part of the AttributeUsage attribute's signature. Whoa for circular dependencies!
[AttributeUsageAttribute(AttributeTargets.Class, Inherited = true)]
public sealed class AttributeUsageAttribute : Attribute
Attributes are a kind of meta data for tagging classes. This is often used in WinForms for example to hide controls from the toolbar, but can be implemented in your own application to enable instances of different classes to behave in specific ways.
Start by creating an attribute:
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)]
public class SortOrderAttribute : Attribute
{
public int SortOrder { get; set; }
public SortOrderAttribute(int sortOrder)
{
this.SortOrder = sortOrder;
}
}
All attribute classes must have the suffix "Attribute" to be valid.
After this is done, create a class that uses the attribute.
[SortOrder(23)]
public class MyClass
{
public MyClass()
{
}
}
Now you can check a specific class' SortOrderAttribute (if it has one) by doing the following:
public class MyInvestigatorClass
{
public void InvestigateTheAttribute()
{
// Get the type object for the class that is using
// the attribute.
Type type = typeof(MyClass);
// Get all custom attributes for the type.
object[] attributes = type.GetCustomAttributes(
typeof(SortOrderAttribute), true);
// Now let's make sure that we got at least one attribute.
if (attributes != null && attributes.Length > 0)
{
// Get the first attribute in the list of custom attributes
// that is of the type "SortOrderAttribute". This should only
// be one since we said "AllowMultiple=false".
SortOrderAttribute attribute =
attributes[0] as SortOrderAttribute;
// Now we can get the sort order for the class "MyClass".
int sortOrder = attribute.SortOrder;
}
}
}
If you want to read more about this you can always check out MSDN which has a pretty good description.
I hope this helped you out!
An attribute is a class that contains some bit of functionality that you can apply to objects in your code. To create one, create a class that inherits from System.Attribute.
As for what they're good for... there are almost limitless uses for them.
http://www.codeproject.com/KB/cs/dotnetattributes.aspx
Attributes are like metadata applied to classes, methods or assemblies.
They are good for any number of things (debugger visualization, marking things as obsolete, marking things as serializable, the list is endless).
Creating your own custom ones is easy as pie. Start here:
http://msdn.microsoft.com/en-us/library/sw480ze8(VS.71).aspx
In the project I'm currently working on, there is a set of UI objects of various flavours and an editor to assembly these objects to create pages for use in the main application, a bit like the form designer in DevStudio. These objects exist in their own assembly and each object is a class derived from UserControl and has a custom attribute. This attribute is defined like this:
[AttributeUsage (AttributeTargets::Class)]
public ref class ControlDescriptionAttribute : Attribute
{
public:
ControlDescriptionAttribute (String ^name, String ^description) :
_name (name),
_description (description)
{
}
property String ^Name
{
String ^get () { return _name; }
}
property String ^Description
{
String ^get () { return _description; }
}
private:
String
^ _name,
^ _description;
};
and I apply it to a class like this:
[ControlDescription ("Pie Chart", "Displays a pie chart")]
public ref class PieControl sealed : UserControl
{
// stuff
};
which is what the previous posters have said.
To use the attribute, the editor has a Generic::List <Type> containing the control types. There is a list box which the user can drag from and drop onto the page to create an instance of the control. To populate the list box, I get the ControlDescriptionAttribute for the control and fill out an entry in the list:
// done for each control type
array <Object ^>
// get all the custom attributes
^attributes = controltype->GetCustomAttributes (true);
Type
// this is the one we're interested in
^attributetype = ECMMainPageDisplay::ControlDescriptionAttribute::typeid;
// iterate over the custom attributes
for each (Object ^attribute in attributes)
{
if (attributetype->IsInstanceOfType (attribute))
{
ECMMainPageDisplay::ControlDescriptionAttribute
^description = safe_cast <ECMMainPageDisplay::ControlDescriptionAttribute ^> (attribute);
// get the name and description and create an entry in the list
ListViewItem
^item = gcnew ListViewItem (description->Name);
item->Tag = controltype->Name;
item->SubItems->Add (description->Description);
mcontrols->Items->Add (item);
break;
}
}
Note: the above is C++/CLI but it's not difficult to convert to C#
(yeah, I know, C++/CLI is an abomination but it's what I have to work with :-( )
You can put attributes on most things and there are whole range of predefined attributes. The editor mentioned above also looks for custom attributes on properties that describe the property and how to edit it.
Once you get the whole idea, you'll wonder how you ever lived without them.
As said, Attributes are relatively easy to create. The other part of the work is creating code that uses it. In most cases you will use reflection at runtime to alter behavior based on the presence of an attribute or its properties. There are also scenarios where you will inspect attributes on compiled code to do some sort of static analysis. For example, parameters might be marked as non-null and the analysis tool can use this as a hint.
Using the attributes and knowing the appropriate scenarios for their use is the bulk of the work.
Attributes are, essentially, bits of data you want to attach to your types (classes, methods, events, enums, etc.)
The idea is that at run time some other type/framework/tool will query your type for the information in the attribute and act upon it.
So, for example, Visual Studio can query the attributes on a 3rd party control to figure out which properties of the control should appear in the Properties pane at design time.
Attributes can also be used in Aspect Oriented Programming to inject/manipulate objects at run time based on the attributes that decorate them and add validation, logging, etc. to the objects without affecting the business logic of the object.
You can use custom attributes as a simple way to define tag values in sub classes without having to write the same code over and over again for each subclass. I came across a nice concise example by John Waters of how to define and use custom attributes in your own code.
There is a tutorial at http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx
To get started creating an attribute, open a C# source file, type attribute and hit [TAB]. It will expand to a template for a new attribute.
Attributes are also commonly used for Aspect Oriented Programming. For an example of this check out the PostSharp project.