Attributes on constants? Haven’t thought about that…

I’m currently reading this article on CodeProject where the author is creating an MVP framework (seems like a good article so far…). In there, the author applies attributes to constants of a type. I had never thought that was actually possible. I want to make sure I keep that at the back of my mind, because I think I’ll be using it sometime soon.

As a quick reminder, this is how that can be implemented:

public class SomeClass
{
    [Special("Some special attribute")]
    public const string SomeConst = "This is some constant";
}

public class SpecialAttribute : Attribute
{
    public string Foo { get; set; }
    public SpecialAttribute(string foo)
    {
        Foo = foo;
    }
}

This blog post has a handy method to get a list of constants defined on a type (including its baseclasses):

/// <SUMMARY>
/// This method will return all the constants from a particular
/// type including the constants from all the base types
/// </SUMMARY>
/// <PARAM NAME="TYPE">type to get the constants for</PARAM>
/// <RETURNS>array of FieldInfos for all the constants</RETURNS>
private FieldInfo[] GetConstants(System.Type type)
{
    ArrayList constants = new ArrayList();

    FieldInfo[] fieldInfos = type.GetFields(
        // Gets all public and static fields

        BindingFlags.Public | BindingFlags.Static |
        // This tells it to get the fields from all base types as well

        BindingFlags.FlattenHierarchy);

    // Go through the list and only pick out the constants
    foreach (FieldInfo fi in fieldInfos)
        // IsLiteral determines if its value is written at 
        //   compile time and not changeable
        // IsInitOnly determine if the field can be set 
        //   in the body of the constructor
        // for C# a field which is readonly keyword would have both true 
        //   but a const field would have only IsLiteral equal to true
        if (fi.IsLiteral && !fi.IsInitOnly)
            constants.Add(fi);

    // Return an array of FieldInfos
    return (FieldInfo[])constants.ToArray(typeof(FieldInfo));
}

And here’s a little test method to show how to get the attributes out of the constants of a type:

[TestMethod]
public void TestMethod1()
{
    SomeClass obj = new SomeClass();

    FieldInfo[] fields = GetConstants(obj.GetType());

    Assert.AreEqual(1, fields.Length);
    Assert.AreEqual("SomeConst", fields[0].Name);

    object[] attribs = fields[0].GetCustomAttributes(false);
    Assert.AreEqual(1, attribs.Length);

    SpecialAttribute special = attribs[0] as SpecialAttribute;
    Assert.IsNotNull(special);
    Assert.AreEqual("Some special attribute", special.Foo);
    
}
  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: