9

我有这个代码的功能:

foreach (PropertyInfo propertyInfo in typeof(T).GetProperties()){
//SOME CODE
if (propertyInfo.CanWrite)
    propertyInfo.SetValue(myCopy, propertyInfo.GetValue(obj, null), null);
}

我会避免检查“收藏”属性;现在我要插入这个控件:

 if (propertyInfo.PropertyType.Name.Contains("List")
     || propertyInfo.PropertyType.Name.Contains("Enumerable")
     || propertyInfo.PropertyType.Name.Contains("Collection"))
     continue;

但是,它不喜欢我!

哪种方法更好?

4

3 回答 3

16

我在想你可能想检查属性实现的类型的接口。(删除了冗余接口,因为 IList 继承 ICollection 而 ICollection 继承 IEnumerable。)

static void DoSomething<T>()
{
    List<Type> collections = new List<Type>() { typeof(IEnumerable<>), typeof(IEnumerable) };

    foreach (PropertyInfo propertyInfo in typeof(T).GetProperties())
    {
        if (propertyInfo.PropertyType != typeof(string) && propertyInfo.PropertyType.GetInterfaces().Any(i => collections.Any(c => i == c)))
        {
            continue;
        }

        Console.WriteLine(propertyInfo.Name);
    }
}

我添加了不拒绝字符串的代码,因为它也实现了 IEnumerable,我想您可能希望保留这些代码。

鉴于之前的集合接口列表的冗余,像这样编写代码可能更简单

static void DoSomething<T>()
{
    foreach (PropertyInfo propertyInfo in typeof(T).GetProperties())
    {
        if (propertyInfo.PropertyType != typeof(string)
            && propertyInfo.PropertyType.GetInterface(typeof(IEnumerable).Name) != null
            && propertyInfo.PropertyType.GetInterface(typeof(IEnumerable<>).Name) != null)
        {
            continue;
        }

        Console.WriteLine(propertyInfo.Name);
    }
}
于 2010-05-14T14:21:01.857 回答
9

我可能会检查一下IEnumerable

if ((typeof(string) != propertyInfo.PropertyType) 
    && typeof(IEnumerable).IsAssignableFrom(propertyInfo.PropertyType))
{
    continue;
}
于 2010-05-14T14:10:24.487 回答
5
bool isCollection = typeof(System.Collections.IEnumerable)
                          .IsAssignableFrom(propertyInfo.PropertyType);
于 2010-05-14T14:11:53.243 回答