RSS

Tag Archives: Attribute

An attribute argument must be a constant expression, typeof expression […]

An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

Working with attributes might be very useful, but in the case when you get such an error it might be frustrating solving it

Attribute Error Image
Error 1 An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type.

So what have I done? Well good question.

Well you have no other option but to thoroughly search all your attributes classes for the failing one, because you have no information where and because this error occurs.

After some tries I figured out which Attribute class was the failing one. But I had no clue why.

My code looked like following:

public class MyCustomAttribute : Attribute
{
    public MyCustomAttribute(string s1 , string s2= null)
    {}
}

and I used the attribute like follows:

[MyCustomAttribute("hello")]

In the other hand following attribute usage worked:

[MyCustomAttribute("hello","world")]

Therefore I tried to split the constructor into two and eliminated the optional parameter. Wow it worked. Therefore the solution is to not use optional parameters in Attributes.

 
Leave a comment

Posted by on July 10, 2011 in C-Sharp

 

Tags:

Get desired Attribute of any Enum

A very interesting feature that I was missing is to get a specific attribute that is set on an enum.

public static T GetAttribute<T>(this Enum enumObj) where T : Attribute
{
    FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());

    if (fieldInfo == null)
        throw new InvalidOperationException("The value "  + enumObj +
                        " ist not defined as a member of the enum" + enumObj.GetType() + ".");

    object[] attribArray = fieldInfo.GetCustomAttributes(typeof(T), false);

    if (attribArray.Length == 0)
        throw new InvalidOperationException(typeof(T) + " ist not an attribute of " +
                        enumObj.GetType());

    try
    {
        return (T)Convert.ChangeType(attribArray[0], typeof(T));
    }
    catch (System.Exception)
    {
        throw new InvalidOperationException("Cannot cast " + attribArray[0].GetType() + " to " +
                        typeof(T) + ". Please specify the generic parameter to its correct type.");
    }
}

This piece can be used as en extension method on every enum. As generic parameter T you should use the type of the attribute you want to get from the enum.

Note
* The attribute you want to get has to be set on the enum.
* You should always be precise with the type of generic parameter T, to get exactly the Attribute you desire.
* On enums with the Flag attribute set, this method will not work everytime.

Example: By passing “Attribute” as parameter T you will get a InvalidCastException if the DescriptionAttribute is set. It has also no sense to pass “Attribute” because then, in the best case, you will get the first attribute that is set on the enum.

Example:

public enum Month
{
    [Description("1st month of the year")]
    January,
    [Description("2dn month of the year")]
    February,
    [Description("3rd month of the year")]
    March,
    [...]
}

Reading the description from the value is done following:

Month m = Month.January;
string s = m.GetAttribute<DescriptionAttribute>().Description;

The value of variable s is then “1st month of the year”.

Flag enum

Example of an enum with flag attribute set:

[Flags]
public enum Month
{
    [Description("1st month of the year")]
    January= 0x1,
    [Description("2dn month of the year")]
    February= 0x2,
    [Description("3rd month of the year")]
    March= 0x4,
    [Description("4th month of the year")]
    April= 0x8,
    [Description("5th month of the year")]
    May= 0x10,
    [Description("6th month of the year")]
    June= 0x20,
    [...]
    [Description("12th month of the year")]
    December= 0x1000,
    [Description("All months in spring")]
    Spring = March | April | May | June,
    [Description("All months in winter")]
    Spring = December | January | February | March,
}

Please be avare of using flags on enums when you call GetArrtibute().
The problem is of its internal nature. The values the fields in the flag enum has to be of power of 2.
Therefore considering the example above, if you set flag Jannuary | February the resulting value is 3, but 3 is not defined as a value in the bitfield.
Therefore it doesn’t exist a description for value 3.

An example that works:

Month m= Month.Spring;
string s = m.GetAttribute<DescriptionAttribute>().Description;

The value of string s is:
All months in spring

Another example that won’t work

Months m = Month.Spring | Month.Winter;
string s= m.GetAttribute<DescriptionAttribute>().Description;

Here we will get an InvalidOperationException saying.
The value “Spring, Winter” ist not defined as a member of the enum Month.

 
2 Comments

Posted by on September 24, 2010 in C-Sharp

 

Tags: ,