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); }