Generics and reflection. How to check type?

Hi all,

If I use the following declaration for a field:

       private List<MyClass> allObjs;

and use reflection to get the type of "allObjs", the following test fails:

       FieldInfo[] crAllFields = objType.GetFields(
                BindingFlags.FlattenHierarchy |
                BindingFlags.Public |
                BindingFlags.NonPublic |
                BindingFlags.Instance
        );

       foreach (FieldInfo crField in crAllFields)
       {
......
       Type crType = crField.FieldType;
       if (crType is IList)
......


Checking the declaration of List<T> (from the manifest), I can see that List<T> implements IList along with some other interfaces. Then why can't I cast it as IList The test gives "false", which doesn't look logical.

This is the declaration of List<T> in the framework:
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable

Or, is there another way to check in my reflection code if the field is a List (my code needs to work on generic lists as well as normal lists).

Thanks for any tips,
Gabriel


Answer this question

Generics and reflection. How to check type?

  • Anthony Cook

    Hmm, isn't there any other way I don't have access to any instance, my code works on types.
    In fact, I'm trying to convert classes to valid SQL code (in this case, "CREATE TABLE"), so my method takes a type parameter and then enumerates the fields. In case of any IList, I have to create join tables.

    I see your point, but the code works very well for base types, just not for interfaces.
    For example, the following snippet works:
    ...
                if (crType == typeof(string))
                {
                    // string -> VARCHAR
                    tempSQL.Append("VARCHAR(" + fieldLength.ToString() + ")");
                }
                else if (crType == typeof(int))
                {
                    // int -> INTEGER
                    tempSQL.Append("INTEGER");
                }

    ...

    There are cases when I have an instance, just not in this method Sad

    Thanks,
    Gabriel

  • Junrei

    A better solution would be to use


    if (typeof(IList).IsAssignableFrom(crType))
    {
    ...
    }

     


    Jon



  • svincoll4

    >Then why can't I cast it as IList The test gives "false", which doesn't look logical.

    What you're doing is checking if the field type, a System.Type, implements IList. What you probably want to do instead is

    if (crField.GetValue(objType) is IList)



  • Michael Dyrnaes

    Found a way, not sure if it is the best or only, looks a bit ugly to me but it works:

    ...
    Type[] fi = crType.FindInterfaces(TypeFilter.Equals, typeof(IList));
    if (fi.Length > 0)

    ...

    The test works for all fields defined as lists.

    You oriented me to the good way, thanks a lot Smile

    Gabriel

  • Generics and reflection. How to check type?