views:

8254

answers:

7

I have seen the following code:

[DefaultValue(100)]
[Description("Some descriptive field here")]
public int MyProperty{...}

The functionality from the above snippit seems clear enough, I have no idea as to how I can use it to do useful things. Im not even sure as to what name to give it!

Does anyone know where I can find more information/a tutorial on these property attributes? I would be also interested in any novel / useful tasks this feature can do.

+2  A: 

These attributes customize the design time experience.

http://msdn.microsoft.com/en-us/library/a19191fh.aspx

Greg Dean
+4  A: 

The ones in your example is used by the visual designer (i.e. MS Expression Blend and Visual Studio designer) to give hints in the designer UI.

Note that they are metadata and will not affect the property logic. Setting DefaultValue for instance will not set the property to that value by default, you have to do that manually.

If you for some reason want to access these attributes, you would have to use reflection.

See MSDN for more information about designer attributes.

Isak Savo
They're also used in the Visual Studio designer.
Joel Coehoorn
And it's important to note that they are just hints: you still have to set your MyPoperty's default value to 100 in the code, for example, or you'll end up lying to your property's consumer.
Joel Coehoorn
+4  A: 

They are called Attributes, there is a lot of information in msdn, e.g. http://msdn.microsoft.com/en-us/library/z0w1kczw.aspx

In general they don't "do" anything on their own, they are used by some other code that will use your class. XmlSerialization is a good example: XmlSerializer (provided by Microsoft as part of the framework) can almost any class (there are a number of requirements on the class though) - it uses reflection to see what data is contained in the class. You can use attributes (defined together with XmlSerializer) to change the way XmlSerializer will serialize your class (e.g. tell it to save the data as attribute instead of an element).

Grzenio
+14  A: 

The functionality from the above snippit seems clear enough,

Maybe not, as many people think that [DefaultValue()] sets the value of the property. Actually, all it does to tell some visual designer (e.g. Visual Studio), what the code is going to set the default value to. That way it knows to bold the value in the Property Window if it's set to something else.

James Curran
So if I did not explicitly set MyProperty to another value, the form designer (or equivelent) would set MyProperty to 100 behind the scenes?
TK
NO! If you do not explicit set MyProperty to a value, it will default to 0 (assuming a backing store). The form designer will display the value as "0", but bolded, to imply to was manually changed from the default. If only affects the look of the value in the form designer.
James Curran
Ahhh that makes some sense. Thanks!
TK
+6  A: 

People have already covered the UI aspect - attributes have other uses, though... for example, they are used extensively in most serialization frameworks. Some attributes are given special treatment by the compiler - for example, [PrincipalPermission(...)] adds declarative security to a method, allowing you to (automatically) check that the user has suitable access.

To add your own special handling, you can use PostSharp; there are many great examples of using PostSharp to do AOP things, like logging - or just code simplification, such as with automatic INotifyPropertyChanged implementation.

Marc Gravell
A: 

Those specific attributes affect the property grid (among other things - the DefaultValue attribute also affects XML serialization).

I use the property grid to allow the user to edit a settings object or various other similar things. DefaultValue, Description, and DisplayName make this very useful.

Jon B
+2  A: 

Hello,

We use it to define which graphical designer should be loaded to configure an instance of a specific type.

That is to say, we have a kind of workflow designer which loads all possible command types from an assembly. These command types have properties that need to be configured, so every command type has the need for a different designer (usercontrol).

For example, consider the following command type (called a composite in our solution)

[CompositeMetaData("Delay","Sets the delay between commands",1)]
[CompositeDesigner(typeof(DelayCompositeDesigner))]
public class DelayComposite : CompositeBase 
{
       // code here
}

This is information is used in two places

1) When the designer creates a list of commands, it uses the CompositeMetaData to display more information about the command.

2) When the user adds a command to the designer and the designer creates an instance of that class, it looks at the CompositeDesigner property, creates a new instance of the specified type (usercontrol) and adds it to the visual designer.

Consider the following code, we use to load the commands into our "toolbar":

    foreach (Type t in assembly.GetExportedTypes())  
    {
        Console.WriteLine(t.Name);

        if (t.Name.EndsWith("Composite"))
        {
            var attributes = t.GetCustomAttributes(false);
            ToolboxListItem item = new ToolboxListItem();

            CompositeMetaDataAttribute meta = (CompositeMetaDataAttribute)attributes
                       .Where(a => a.GetType() == typeof(Vialis.LightLink.Attributes.CompositeMetaDataAttribute)).First();
            item.Name = meta.DisplayName;
            item.Description = meta.Description;
            item.Length = meta.Length;
            item.CompositType = t;

            this.lstCommands.Items.Add(item);
        }                           
    }

As you can see, for every type in the assembly of which the name ends with "Composite", we get the custom attributes and use that information to populate our ToolboxListItem instance.

As for loading the designer, the attribute is retreived like this:

var designerAttribute = (CompositeDesignerAttribute)item.CompositType.GetCustomAttributes(false)
                         .Where(a => a.GetType() == typeof(CompositeDesignerAttribute)).FirstOrDefault();

This is just one example of how you might be able to use custom attributes,

I hope this gives you a place to start.

TimothyP