1

Here is my attribute definition:

[AttributeUsage(AttributeTargets.Field)]
public class Optional : System.Attribute
{
    public Optional()
    {
    }
}

In MyClass:

[Optional] public TextBox Name;

Finally in another function:

typeof(MyClass).GetFields().ToList<FieldInfo>().ForEach(x => writer.WriteLine(
   x.FieldType + " is called " + 
   x.Name + " and has attributes " + 
   x.GetCustomAttributes(true)[0]
 ));

The problem is I get an error for index 0. I just want to check for fields where the attribute is applied. The error goes away when I remove x.GetCustomAttributes(true)[0].

Exact Error:

Exception Details: System.IndexOutOfRangeException: Index was outside the bounds of the array.

Source Error:

Line 63:             }
Line 64: 
Line 65:             typeof(T).GetFields().ToList<FieldInfo>().ForEach(x => writer.WriteLine(x.FieldType + " is called " + 
Line 66:                 x.Name + " and has attributes " + 
Line 67:                 x.GetCustomAttributes(true)[0]+ "</br>"));
1
  • Added - Keep in mind this goes away if I remove the "GetCustomAttributes" part. Commented Feb 26, 2011 at 8:04

3 Answers 3

2

Seems like there might be two questions here. To find all the fields that have your [Optional] attribute, you want:

typeof(MyClass).GetFields().Where(
   f => f.GetCustomAttributes(typeof(OptionalAttribute), true).Any())

To write out the custom attributes on all your fields, you want:

typeof(MyClass).ToList<FieldInfo>().ForEach(x => 
{
 writer.WriteLine(
   x.FieldType + " is called " + 
   x.Name + " and has attributes " + 
   string.Join(", ", x.GetCustomAttributes(true).Select(a => a.ToString()).ToArray()));
});
Sign up to request clarification or add additional context in comments.

1 Comment

The first part you gave allowed me the most eloquent solution to my problem. Thank you.
1

Check the attribute existence like this:

x.GetCustomAttributes(true).Any(item => item is OptionalAttribute)

I have assumed that you will rename your Optional attribute to OptionalAttribute as all attributes should have the "Attribute" suffix.

Comments

1

As you seem to have gathered, you are getting this error because you are trying to get the 0th element of an empty array, which is of course illegal. You need to filter out the fields without any attributes first, like so:

var fields = from fieldInfo in typeof(MyClass).GetFields()
             let Attributes = fieldInfo.GetCustomAttributes(true)
             where Attributes.Any()
             select new { fieldInfo.FieldType, fieldInfo.Name, Attributes };

foreach (var field in fields)
{
    writer.WriteLine(field.FieldType + " is called " +
                     field.Name + " and its first attribute is " +
                     field.Attributes.First());
}

If you are specifically interested in those with OptionalAttribute, then you are probably looking for something like this instead:

var fields = from fieldInfo in typeof(MyClass).GetFields()
             let attributes = fieldInfo.GetCustomAttributes(true).OfType<OptionalAttribute>()
             where attributes.Any()
             select new { fieldInfo.FieldType, fieldInfo.Name, Attribute = attributes.Single() };

foreach (var field in fields)
{
    writer.WriteLine(field.FieldType + " is called " +
                     field.Name + " and its OptionalAttribute is " +
                     field.Attribute);
}

1 Comment

You nailed it that the problem was with multiple elements not having the attribute defined. I wish I could accept your answer as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.