Getting the attributes of a field using reflection in C#

Mr. Smith picture Mr. Smith · Sep 13, 2009 · Viewed 19.7k times · Source

I wrote a method that extracts fields from an object like this:

private static string GetHTMLStatic(ref Object objectX, ref List<string> ExludeFields)
{
    Type objectType = objectX.GetType();
    FieldInfo[] fieldInfo = objectType.GetFields();

    foreach (FieldInfo field in fieldInfo)
    {
        if(!ExludeFields.Contains(field.Name))
        {
            DisplayOutput += GetHTMLAttributes(field);
        }                
    }

    return DisplayOutput;
}

Each field in my class also has it's own attributes, in this case my attribute is called HTMLAttributes. Inside the foreach loop I'm trying to get the attributes for each field and their respective values. It currently looks like this:

private static string GetHTMLAttributes(FieldInfo field)
{
    string AttributeOutput = string.Empty;

    HTMLAttributes[] htmlAttributes = field.GetCustomAttributes(typeof(HTMLAttributes), false);

    foreach (HTMLAttributes fa in htmlAttributes)
    {
        //Do stuff with the field's attributes here.
    }

    return AttributeOutput;
}

My attributes class looks like this:

[AttributeUsage(AttributeTargets.Field,
                AllowMultiple = true)]
public class HTMLAttributes : System.Attribute
{
    public string fieldType;
    public string inputType;

    public HTMLAttributes(string fType, string iType)
    {
        fieldType = fType.ToString();
        inputType = iType.ToString();
    }
}

This seems logical but it won't compile, I have a red squiggly line in the GetHTMLAttributes() method under:

field.GetCustomAttributes(typeof(HTMLAttributes), false);

The field I'm trying to extract the attributes from is in another class used like this:

[HTMLAttributes("input", "text")]
public string CustomerName;

From my understanding (or lack thereof) this should work? Please expand my mind fellow developers!

*Edit, compiler error:

Cannot implicitly convert type 'object[]' to 'data.HTMLAttributes[]'. An explicit conversion exists (are you missing a cast?)

I have tried casting it like this:

(HTMLAttributes)field.GetCustomAttributes(typeof(HTMLAttributes), false);

But that also doesn't work, I get this compiler error:

Cannot convert type 'object[]' to 'data.HTMLAttributes'

Answer

mmx picture mmx · Sep 13, 2009

GetCustomAttributes method returns an object[], not HTMLAttributes[]. The reason it returns object[] is that it has been there since 1.0, before .NET generics see the light of day.

You should manually cast each item in the return value to HTMLAttributes.

To fix your code, you simply need to change the line to:

object[] htmlAttributes = field.GetCustomAttributes(typeof(HTMLAttributes), false);

foreach will take care of the cast for you.

Update:

You shouldn't cast the returned array to HTMLAttributes[]. The return value is not HTMLAttributes[]. It's an object[] containing elements of type HTMLAttributes. If you want a HTMLAttribute[] typed object (which you don't need in this specific code snippet, foreach would suffice), you should cast each element of array individually to HTMLAttribute; perhaps using LINQ:

HTMLAttributes[] htmlAttributes = returnValue.Cast<HTMLAttributes>().ToArray();