反射实现自定义Required属性验证器:值与default比较异常
模型验证器值比较问题的原因与解决
问题根源
你碰到的问题核心是装箱类型不匹配:
prop.GetValue(testObject)返回的是object类型,非可空值类型(比如int)的取值会被装箱成object实例(比如值为0的int会变成包装后的object)。- 直接写
default时,编译器会自动推断它是object类型的默认值——也就是null。 - 相当于你在做
装箱后的int(0) == null的比较,结果必然是false,哪怕实际值确实是该类型的默认值。
解决方法
要针对属性的实际类型获取对应默认值再做比较,推荐两种实用方式:
方式一:通过属性类型动态生成默认值
var propType = prop.PropertyType; // 值类型用Activator创建默认实例,引用类型直接取null var defaultValue = propType.IsValueType ? Activator.CreateInstance(propType) : null; // 用object.Equals处理装箱值的比较 if (object.Equals(prop.GetValue(testObject), defaultValue)) { // 执行验证不通过的逻辑 }
方式二:泛型方法辅助获取默认值
先定义一个泛型工具方法:
public static class DefaultHelper { public static T GetDefault<T>() => default; }
然后通过反射调用这个方法,获取对应属性类型的默认值:
var getDefaultMethod = typeof(DefaultHelper).GetMethod("GetDefault").MakeGenericMethod(prop.PropertyType); var defaultValue = getDefaultMethod.Invoke(null, null); if (object.Equals(prop.GetValue(testObject), defaultValue)) { // 执行验证不通过的逻辑 }
补充:可空类型的兼容处理
结合你原来的逻辑,先判断是否为可空类型,再分支处理:
var underlyingType = Nullable.GetUnderlyingType(prop.PropertyType); bool isNullable = underlyingType != null; if (isNullable) { if (prop.GetValue(testObject) == null) { // 可空类型为null,验证不通过 } } else { var defaultValue = prop.PropertyType.IsValueType ? Activator.CreateInstance(prop.PropertyType) : null; if (object.Equals(prop.GetValue(testObject), defaultValue)) { // 非可空值类型为默认值,验证不通过 } }
内容的提问来源于stack exchange,提问作者AKozak
相关产品推荐
相关产品推荐

