【问题标题】:How would I know if a property is a generic collection我怎么知道一个属性是否是一个通用集合
【发布时间】:2010-12-06 23:03:40
【问题描述】:

我需要知道类中的属性类型是否是使用 PropertyInfo 类的泛型集合(List、ObservableCollection)。

foreach (PropertyInfo p in (o.GetType()).GetProperties())
{
    if(p is Collection<T> ????? )

}

【问题讨论】:

    标签: c# generics collections propertyinfo


    【解决方案1】:

    GetGenericTypeDefinitiontypeof(Collection&lt;&gt;) 将完成这项工作:

    if(p.PropertyType.IsGenericType && typeof(Collection<>).IsAssignableFrom(p.PropertyType.GetGenericTypeDefinition())
    

    【讨论】:

    • 您不应该针对ICollection&lt;T&gt; 而不是Collection&lt;T&gt; 进行测试吗?许多通用集合(例如List&lt;T&gt;)不继承自Collection&lt;T&gt;
    • p.GetType() 将返回一个 Type 描述 RuntimePropertyInfo 而不是属性的类型。 GetGenericTypeDefinition() 也会为非泛型类型抛出异常。
    • 没错,GetGenericTypeDefinition 会为非泛型类型抛出异常。
    • 我正在使用这个pi[index].PropertyType.IsGenericType &amp;&amp; typeof(ICollection&lt;&gt;).IsAssignableFrom(pi[index].PropertyType.GetGenericTypeDefinition()) 并且非常适合我的情况
    【解决方案2】:
    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<>");
        }
    }
    

    您需要测试t.IsGenericTypex.IsGenericType,否则GetGenericTypeDefinition() 将在类型不是泛型时抛出异常。

    如果属性声明为ICollection&lt;T&gt;,则tColl.IsAssignableFrom(t.GetGenericTypeDefinition()) 将返回true

    如果属性被声明为实现ICollection&lt;T&gt;的类型,那么 t.GetInterfaces().Any(x =&gt; x.IsGenericType &amp;&amp; x.GetGenericTypeDefinition() == tColl) 将返回 true

    请注意,tColl.IsAssignableFrom(t.GetGenericTypeDefinition()) 会返回 false,例如 List&lt;int&gt;


    我已经为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; }
    }
    

    输出:

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

    【讨论】:

      猜你喜欢
      • 2011-11-23
      • 2019-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-28
      • 2021-05-17
      相关资源
      最近更新 更多