How would I know if a property is a generic collection

前端 未结 2 985
借酒劲吻你
借酒劲吻你 2021-02-13 13:24

I need to know if the type of a property in a class is a generic collection (List, ObservableCollection) using the PropertyInfo class.

foreach (PropertyInfo p          


        
相关标签:
2条回答
  • 2021-02-13 13:59
    Type tColl = typeof(ICollection<>);
    foreach (PropertyInfo p in (o.GetType()).GetProperties()) {
        Type t = p.PropertyType;
        if (t.IsGenericType && tColl.IsAssignableFrom(t.GetGenericTypeDefinition()) ||
            t.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == tColl)) {
            Console.WriteLine(p.Name + " IS an ICollection<>");
        } else {
            Console.WriteLine(p.Name + " is NOT an ICollection<>");
        }
    }
    

    You need the tests t.IsGenericType and x.IsGenericType, otherwise GetGenericTypeDefinition() will throw an exception if the type is not generic.

    If the property is declared as ICollection<T> then tColl.IsAssignableFrom(t.GetGenericTypeDefinition()) will return true.

    If the property is declared as a type which implements ICollection<T> then t.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == tColl) will return true.

    Note that tColl.IsAssignableFrom(t.GetGenericTypeDefinition()) returns false for a List<int> for example.


    I have tested all these combinations for MyT o = new MyT();

    private interface IMyCollInterface1 : ICollection<int> { }
    private interface IMyCollInterface2<T> : ICollection<T> { }
    private class MyCollType1 : IMyCollInterface1 { ... }
    private class MyCollType2 : IMyCollInterface2<int> { ... }
    private class MyCollType3<T> : IMyCollInterface2<T> { ... }
    
    private class MyT
    {
        public ICollection<int> IntCollection { get; set; }
        public List<int> IntList { get; set; }
        public IMyCollInterface1 iColl1 { get; set; }
        public IMyCollInterface2<int> iColl2 { get; set; }
        public MyCollType1 Coll1 { get; set; }
        public MyCollType2 Coll2 { get; set; }
        public MyCollType3<int> Coll3 { get; set; }
        public string StringProp { get; set; }
    }
    

    Output:

    IntCollection IS an ICollection<>
    IntList IS an ICollection<>
    iColl1 IS an ICollection<>
    iColl2 IS an ICollection<>
    Coll1 IS an ICollection<>
    Coll2 IS an ICollection<>
    Coll3 IS an ICollection<>
    StringProp is NOT an ICollection<>
    
    0 讨论(0)
  • 2021-02-13 14:25

    GetGenericTypeDefinition and typeof(Collection<>) will do the job:

    if(p.PropertyType.IsGenericType && typeof(Collection<>).IsAssignableFrom(p.PropertyType.GetGenericTypeDefinition())
    
    0 讨论(0)
提交回复
热议问题