我怎么知道属性是否是泛型集合

Lan*_*nce 13 c# generics collections propertyinfo

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

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

}
Run Code Online (Sandbox Code Playgroud)

Oli*_*bes 31

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<>");
    }
}
Run Code Online (Sandbox Code Playgroud)

你需要测试t.IsGenericTypex.IsGenericType,否则,GetGenericTypeDefinition()如果该类型是不是通用会抛出异常.

如果声明属性,ICollection<T>tColl.IsAssignableFrom(t.GetGenericTypeDefinition())返回true.

如果属性声明为实现的类型,ICollection<T>t.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == tColl)返回true.

请注意,tColl.IsAssignableFrom(t.GetGenericTypeDefinition())返回false一个List<int>例如.


我测试了所有这些组合 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; }
}
Run Code Online (Sandbox Code Playgroud)

输出:

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<>
Run Code Online (Sandbox Code Playgroud)


Ant*_*lev 12

GetGenericTypeDefinition并且typeof(Collection<>)将做的工作:

if(p.PropertyType.IsGenericType && typeof(Collection<>).IsAssignableFrom(p.PropertyType.GetGenericTypeDefinition())
Run Code Online (Sandbox Code Playgroud)

  • 你不应该测试像`ICollection <T>`而不是`Collection <T>`这样的东西吗?许多泛型集合(例如,`List <T>`)不继承自`Collection <T>`. (4认同)
  • `p.GetType()`将返回一个`Type`,它描述`RuntimePropertyInfo`而不是属性的类型.此外,`GetGenericTypeDefinition()`会抛出非泛型类型的异常. (2认同)