如何从.NET类中提取非数组/集合的单值字段与属性?
从.NET类中提取单值字段/属性的优化实现
你的思路方向是对的,但目前的IsArrayOrCollection方法存在几个小问题,我来分享更严谨、更实用的实现方式:
首先修正集合判断的核心问题
你原来的if (testType is IEnumerable)是错误的——testType是Type类型的实例,它永远不会实现IEnumerable接口。正确的做法是判断该类型是否实现了IEnumerable,同时还要注意一个特殊情况:string虽然实现了IEnumerable<char>,但我们通常把它当作单值类型处理,不能被误判为集合。
优化后的扩展方法
我们可以直接封装一个IsSingleValueType方法,更直观地判断是否为单值类型:
public static bool IsSingleValueType(this Type type) { // 处理可空类型,拆箱到基础类型判断 type = Nullable.GetUnderlyingType(type) ?? type; // 值类型、字符串都是单值 if (type.IsValueType || type == typeof(string)) return true; // 数组直接排除 if (type.IsArray) return false; // 判断是否实现了IEnumerable(排除已处理的字符串) return !typeof(System.Collections.IEnumerable).IsAssignableFrom(type); }
提取单值字段和属性的完整示例
如果需要同时处理字段和属性,可以这样写:
var targetObj = new YourClass(); // 你的目标实例 var bindingFlags = BindingFlags.Public | BindingFlags.Instance; // 根据需求添加NonPublic等 // 提取单值字段 var singleValueFields = targetObj.GetType().GetFields(bindingFlags) .Where(field => field.FieldType.IsSingleValueType()) .ToArray(); // 提取单值属性 var singleValueProperties = targetObj.GetType().GetProperties(bindingFlags) .Where(prop => prop.PropertyType.IsSingleValueType()) .ToArray();
额外注意事项
- 如果需要处理静态成员,记得在
bindingFlags中添加BindingFlags.Static - 对于泛型类型(比如
Nullable<T>),我们用Nullable.GetUnderlyingType拆箱后判断,避免误判 - 如果你的场景中还有其他需要特殊处理的类型(比如自定义的单值包装类),可以在方法中添加额外的判断条件
内容的提问来源于stack exchange,提问作者Bit Racketeer
相关产品推荐
相关产品推荐

