Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I compare types when using generics?

I am trying to derive the type of an object at runtime. Specifically I need to know two things whether it implements ICollection or IDto. Currently my only solution I have been able to find is this:

   private static bool IsACollection(PropertyDescriptor descriptor)
    {
        bool isCollection = false;

        foreach (Type type in descriptor.PropertyType.GetInterfaces())
        {
            if (type.IsGenericType)
            {
                if (type.GetGenericTypeDefinition() == typeof(ICollection<>))
                {
                    isCollection = true;
                    break;
                }
            }
            else
            {
                if (type == typeof(ICollection))
                {
                    isCollection = true;
                    break;
                }
            }
        }


        return isCollection;
    }

    private static bool IsADto(PropertyDescriptor descriptor)
    {
        bool isDto = false;

        foreach (Type type in descriptor.PropertyType.GetInterfaces())
        {
            if (type == typeof(IDto))
            {
                isDto = true;
                break;
            }
        }          
        return isDto;
    }

However I am convinced there has to be a better way than this. I have tried comparing in a normal fashion such as:

if(descriptor.PropertyType == typeof(ICollection<>))

However, this fails when using reflection yet when not using reflection it works fine.

I don't want to iterate through the interfaces for every field of my entity. Could someone shed some light on another method in which to do this? Yes, I am prematurely optimizing, but it looks ugly too so please humor me.

Caveats:

  1. It could or could not be generic, such as IList<> or just ArrayList thus why I am looking for ICollection or ICollection<>. So I assume I should use IsGenericType in an if statement to know whether to test using ICollection<> or not.

Thanks in advance!

like image 648
joshlrogers Avatar asked Jul 29 '09 17:07

joshlrogers


People also ask

How do you compare generic data types in Java?

To compare generic types in Java, use the compareTo method.

How do you compare T types?

If you need to compare objects of type T by more or less, then the IComparable<T> interface will do. Such a comparison is necessary, for example, when sorting. If you need to compare objects of type T for equality/inequality, you can use the IEquatable<T> interface.


2 Answers

This:

type == typeof(ICollection)

will check if the type of property is exactly ICollection. That is, it will return true for:

public ICollection<int> x { get; set; }

but not for:

public List<int> x { get; set; }

If you want to check if the type of property is, or is derived from, ICollection, the simplest way is to use Type.IsAssignableFrom:

typeof(ICollection).IsAssignableFrom(type)

and the same goes for generic:

typeof(ICollection<>).IsAssignableFrom(type.GetGenericTypeDefinition())
like image 194
Pavel Minaev Avatar answered Sep 23 '22 21:09

Pavel Minaev


Does type.IsAssignable help in this case?

EDIT: Sorry, it should have been Type.IsAssignableFrom

like image 31
shahkalpesh Avatar answered Sep 22 '22 21:09

shahkalpesh