Question

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!

Was it helpful?

Solution

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())

OTHER TIPS

Does type.IsAssignable help in this case?

EDIT: Sorry, it should have been Type.IsAssignableFrom

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top