Determining if a generic Type implements ICollection

Hi,

I need to know if MyProperty returns an ICollection<T> for any T.

Given a PropertyInfo instance that has a PropertyType of an IList derivative, for example.

public IList<MyType> MyProperty {

get { return mycollection; }

}

I am iterating through the properties of the type, and would like to know which properties implement an ICollection of any kind. Basically I need to know if MyProperty returns an ICollection<T> for any T.

Is there any way of finding this out

My problem is that I cannot seem to find a way of determining if the property returns a collection of 'any kind' I have to know the exact type of the property which I don't really know at runtime.

I have tried typeof(IList<object>).IsAssignableFrom(propertyInfo.PropertyType), which does not work because an expicit cast is needed for the conversion, not an implicit one.



Answer this question

Determining if a generic Type implements ICollection

  • Edentheguy

    Hi,

    I am not concerned about the compile time List<string> class at all. Nothing about my post referred to compile time. I am in fact attempting to interrogate the generic class structure at runtime using reflection.

    I am trying to establish the relationship between List<T> and IList<T> at runtime, which is certainly possible. My only caveat is that I am attempting to obtain information about this relationship without necessarily knowing the type of T. I have a parent object that contains properties that contain lists of child objects. I am attempting to find which of the parent properties refer to collections of child objects. All I need to know to obtain this information is that the parent property is one of several pre-determined collection types, namely IList, ITypedList, IEnumerable. I have started with IList. I would like to know which of the properties expose IList derivatives. Generic types are available for interrogation at runtime, and there is almost certainly a way to do this. I am sure someone out there will have some additional suggestions.

    You have missed my question completely.

    Kind Regards

    Craig


  • R.Arjun

    Generics is a runtime feature - code for a class containing the actual types is JIT-ted at runtime. For example, when you instantiate a list like this:

    public List<string> listOfStrings = new List<string>();

    Simply put, a list class with T replaced with string is JIT compiled at runtime when this code is called.
    Because of this, you will not have a type representing List of strings at compile-time, and you will thus have no type at compile-time.

    I'm afraid the closest you can get to seeing what is inside your list, is by calling GetType() in the instance - you will see something like

    System.Collections.Generic.List`1[System.String]




  • Manoj Kumar Goud

    I am supprised that with a generic you cannot obtain Type information of T without having to first create it or pass in Type into a routine like I am having to do here.

    public class EnvDTEToolWindowController<T> : EnvDTEClass

    {

    ...

    public bool ShowToolWindow(Type toolWindowType, string toolWindowCaption, string toolWindowGUID)

    {

    if (toolWindowType == null)

    throw new ArgumentNullException("toolWindowType");

    Type userControl = this.Env.GetType("System.Windows.Forms.UserControl");

    if (userControl == null)

    throw new NullReferenceException("userControl is null");

    if (!toolWindowType.IsSubclassOf(userControl))

    throw new Exception("toolWindowType must be of System.Windows.Forms.UserControl Type");

    Please put it on the wish list Wink

    Kenneth



  • Greg Allen

    Check if the type returned by propertyInfo.PropertyType.GetGenericTypeDefinition() implements ICollection<T>.



  • Anand Raman - MSFT

    Hi Mattias,

    Further to my last post, the object being in the incorrect state was my mistake.

    You are correct. The following assertion is true, I am able to test the collection with the following code.

    Type.GetType("System.Collections.Generic.IList`1").Equals(pi.PropertyType.GetGenericTypeDefinition());


  • Nagu

    James, that relies on compile time overload resolution. It won't help when working with reflection at runtime.



  • Michael Collins

    A variation of this should work for you:



    class
    ABC : List<string> {}

    public class MyClass
    {
    public void Code(string[] args)
    {
    ABC abc =
    new ABC();
    string str= "abc";
    Console.WriteLine(Test(abc)); // Prints "Yes"
    Console.WriteLine(Test(str)); // Prints "No"

    }

    string Test<T>(ICollection<T> coll)
    {
    return "Yes";}
    string Test(object obj)
    {
    return "No";}
    }



  • Janetjyothi

    Hi Mattias,

    I think you are definitely on the right track.

    Unfortunately GetGenericTypeDeclaration throws an exception indicating that the object is in an invalid state. I am not certain what "state" is required. Sadly I am trying to do this based on the type information, I do not have an instance. I feel that I might have been a little harsh to the first respondent. He might have been onto something there

    Another option may be to find instances of IEnumerable, but hard code ignoring the string class. I don't think any of the other primitive types support IEnumerable, so that might work in obtaining all the collections exposed by the class.

    Do you have any thoughts

    Regards

    Craig


  • Determining if a generic Type implements ICollection