Conditional Attributes c# - c#

In my program, I have two attributes: VisibleToA and VisibleToB. These are used to restrict visibility of certain functions through the API.
The problem occurs when I need to have a function visible to A or B. Attributes are "anded" together by default such that I create a method:
[VisibleToA(), VisibleToB()]
public void ConditionallyVisibleMethod() { }
It is effectively equivalent to VisibleToAandB. This is a problem because if they are both true, then it makes it impossible for A to see it, since A is not B, and makes it impossible for B to see it, since B is not A.
Because of this, I want to make it visible to A OR B, only needing to satisfy a single condition in order to view it.
So, simple fix, I created an OrConditionAttribute that takes in an array of Attributes. Loop through the condition on each one, if true, return true. Then I found out attributes can only have parameters of primitive types due to how they are written in the metadata.
They have to be attributes, due to how the structure of the program works, so I need to use one in one way or another. I thought about passing in strings representing the attributes' class names, then inside the OrConditionAttribute create an instance of the class from the string name, but I wasn't sure how to pass in parameters as well since VisibleToA and VisibleToB both require parameters.
Is there a way to implement this functionality?

To answer your question directly, unfortunately, there is no way to (declaratively) conditionally apply two attributes to your class/method/property, they are either applied, or not, so in your case you have both VisibleToA and VisibleToB. Values provided to attribute constructors must also be compile-time constants, which is probably also part of your problem.
In terms of your design, it sounds to me like you've got some amount of business logic in your attribute classes themselves, which might be causing your problem. It's generally good design practice to restrict the amount of actual logic contained in attributes, and instead have some other mechanism to interpret the metadata that you've applied to your classes/methods/properties.
If you can change your design, I would suggest something like the following:
public enum VisibilitySpecifier
{
A,
B,
}
public class AndVisibleToAttribute : Attribute
{
public VisibilitySpecifier[] Visibility { get; set; }
public AndVisibleToAttribute(params VisibilitySpecifier[] visibility)
{
Visibility = visibility;
}
}
public class OrVisibleToAttribute : Attribute
{
public VisibilitySpecifier[] Visibility { get; set; }
public OrVisibleToAttribute(params VisibilitySpecifier[] visibility)
{
Visibility = visibility;
}
}
Then, simply process the values in the Visibility property according to the logic defined by the particular attribute chosen.

Related

How the meta tags of a method work? [duplicate]

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.

when and why to use C# accessor methods [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
C# - When to use properties instead of functions
I am trying to understand when and why to use "getters" and "setters"
would someone please provide some guidance.
What is the difference between the following constructs - please look in terms of accessor methods only.
//EXAMPLE 1: simple accessor method
private static bool _isInitialEditMapPageLoad;
public static bool isInitialEditMapPageLoad
{
get {return _isInitialEditMapPageLoad;}
set {_isInitialEditMapPageLoad = value;}
}
//EXAMPLE 2: accessor method with a conditional test
private static bool _isInitialEditMapPageLoad;
public static bool isInitialEditMapPageLoad
{
get
{
if (currentSession[isAuthorizedUseder] == null)
return false;
else
return _isInitialEditMapPageLoad;
}
set {isInitialEditMapPageLoad = value;}
}
//EXAMPLE 3: just a get accessor method - is this the same as EXAMPLE 4?
private static bool _isInitialEditMapPageLoad = false;
public static bool isInitialEditMapPageLoad
{
get {return _isInitialEditMapPageLoad;}
}
//EXAMPLE 4: simple method
private static bool _isInitialEditMapPageLoad = false;
public static bool isInitialEditMapPageLoad
{
return _isInitialEditMapPageLoad;
}
Your getters/setters should be your public interface to your class.
As a rule of thumb, all of your members should be private except for what you want people to have access to outside of your class and you never want your private variables to be directly accessible outside if your class
Here's a simple example. say you had a class that you needed an age variable for. In this case, you could perform validation right there in the setter without your external classes needing to know that the value is validated.
class Person {
int age = 0;
public int Age {
get { return age; }
set {
//do validation
if (valid) {
age = value;
}
//Error conditions if you want them.
}
}
//More getters/setters
}
The reasoning behind Getters/Setters is to protect the class from being broken when a user alters a field in an invalid way, and they allow you to change the implementation of your class while leaving the publicly exposed properties unchanged.
Unless you need some kind of validation or lazy-loaded properties then you can usually just use auto properties.
public string Name { get; set; }
1: This is a simple property, and can be used in much the same way as a public field. If you have a reason to expose both get and set operations to other users (that is, other classes) and you don't need anything fancy, this is it. This can also be written with "auto-properties",
public static bool isInitialEditMapPageLoad {get;set;} // behaves just like example 1
auto props are much faster to write and in my opinion are much more readable than the full declaration (if I see a full declaration with a backing field, I expect to find some complexity).
2: This shows one of the reasons for properties: using some logic to return a value rather than always returning a value directly. Somebody can set this value as they would a public field whenever they want. They can get the value whenever they want, as well, with the caveat that false means either this isn't the initial load OR the user isn't authorized -- that is, some (simple) logic is done before returning a value.
3: This behaves as a public field ONLY for reading -- somebody can retrieve the value, but not set it. This is in essence a value that is read only to outside code (not to be confused with the readonly keyword)
4: Resulted in a compilation error for me. Assuming that is supposed to be a method declaration, manually defining a getter like one would do in Java, then it is similar to example 3. I believe there are other issues that make this not quite the same, like if you want to turn this into a dependency property, etc. Unfortunately my knowledge in that area comes up short.
==========
As a general rule, user properties to limit access to your class data. As a principle, anything that you can keep from allowing other code to touch, should be kept that way. As a practical matter, you will want to be able to set values on classes to change how they display, modify the data represented, et cetera. Use properties to maintain maximum control of this interaction.
If other classes will need to view something in your class, you'll need to expose a getter, but not a setter. This isn't possible with fields, unless you use the Java method of writing a custom getter method. They also allow you to perform calculations or validations before returning or setting data. For example, if you have some integer value that should be within some range (a range which can change depending on the state of your object, even), in your setter you can check to make sure this condition is met before actually updating your value.
Try to avoid the trap of just setting everything as an autoprop -- this is no different than making everything a public field. Keep everything as private as possible. No getters unless necessary, no setters unless necessary, and setters should perform any small logic necessary to verify input before accepting it, if appropriate. That said, avoid the other trap: putting lots of code in getters/setters. If it takes more than a handful of lines, you should probably make a method rather than a property, simply because it gives a greater hint to others using your code that something big is going to happen.
Like others mentioned, use getters/setters when you want the object members to be available to other objects.
Additionally, the readability of yoru code could be improved (if you're on .NET 2.0 or greater) using autoproperties. The examples you have would then be like this:
// example 1
public static bool IsInitialEditMapPageLoad { get; set; }
// example 3/4 - note that false is the default for bools
public static bool IsInitialEditMapPageLoad { get; private set; }
Example 3 would likely stay the same, due to the validation logic being there.

Why would one want to use AttributeUsage AllowMultiple when creating attributes?

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.

C#: Can I remove "{ get; set; }"?

Is there a difference between:
public T RequestedValue { get; set; }
and
public T RequestedValue;
?
Taken from this code:
public class PropertyChangeRequestEventArgs<T>:EventArgs
{
public PropertyChangeRequestEventArgs(T pRequestedValue)
{
RequestedValue = pRequestedValue;
}
public T RequestedValue { get; set; }
}
The first is an Auto-Implemented Property the second is a Field. Regular Properties expose Getters and Setters but have a private field to actually store the value:
private int someProperty;
public int SomeProperty
{
get { return someProperty; }
set { someProperty = value; }
}
The first allows you to change certain aspects of the implementation of your class without affecting all the other code in your application. The most important point is that, with properties, changes can be made without breaking binary compatibility (although a field can often be changed to a property without breaking code). If it is a public member, a property is advisable. (Stealing shamelessly from Snarfblam's comment)
From the Properties page:
Properties are members that provide a flexible mechanism to read, write, or compute the values of private fields. Properties can be used as if they are public data members, but they are actually special methods called accessors. This enables data to be accessed easily and still helps promote the safety and flexibility of methods.
Properties with a backing field are the most flexible form as they allow easy implementation of things like the INotifyPropertyChanged event for updating the UI in Model-View-ViewModel implementations.
deep explanation!
The {get; set;} is an automatic property, while the second is a field.
a field is a normal variable, from some type, that contains data.
a property is a couple of methods (well sometimes it's just one), one for get, and one for set. they only have a syntax like fields, but actually they are quite different.
properties are usually for filtering the set of the value, or virtualizing something in the get, etc.
automatic properties, also create a private field behind the scenes, return its value in the get, and set its value in the set.
seemingly this is just like a normal field, but behind the scenes (IL) using properties is totally different from using fields.
a.Property1 = 4;
is translate into something like:
a.Set_Propert1(4);
and this:
x = a.Property1;
is translate to something like this:
x = a.Get_Property1();
so why is it a good practice to use only public properties, even if they are automatic?
say you are writing a library, that is used by other application, and someday you want to release a new version of that library that constrains one of your class' fields..
if you are using properties, you can just change the property (even if it is an automatic one, you can replace it by a full one), and then any application which used your library can still use it in the same way.
but if you made a public field, which you now want to constrain, you'll need to make a property for this and make the field private, but if you will, any application that used you library will no more be bale to, because the way it use fields and property is different.
You may write:
public T RequestedValue { get; set; }
as a shortcut of:
private T _requestedValue;
public T RequestedValue
{
get { return this._requestedValue; }
set { this._requestedValue = value; }
}
They are totally equivalent, also considering the performance.
The answer is, yes you can remove the { get; set; } but then a whole load subtle differences kick in. Some will say fields and properties express radically different design intent but in practice this distinction has been eroded over the years as C# evolves and progressively blurs the the syntactic differences.
For a good list of compiler-binary level differences between fields and properties refer to SO question difference-between-property-and-field-in-c. But the answers to that question missed one significant point about the special role of properties when declaring interfaces.

What are attributes in .NET?

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.

Categories

Resources