我有一个这个代码的功能:
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;
但是,它不喜欢我!
哪一种更好的方法呢?
解决方法
我在想你可能想要检查接口的属性实现的类型. (删除冗余接口,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); } }