C# 如何确定对象中包装的值为 null 或默认值
本文关键字:null 默认值 包装 何确定 对象 | 更新日期: 2023-09-27 17:55:31
我目前正在编写自定义的必需验证属性,当值为 null 或 Default 时,我想恢复错误。对于默认值,我的意思是字符串的",0表示整数,0.0表示双精度,null表示对象。
为了实现这一点,我调用了以下适用于任何类型的函数
protected bool IsNullOrDefault<T>(T value)
{
return object.Equals(value, default(T));
}
以下是测试:
object obj = null;
bool flag = IsNullOrDefault(obj));
标志 = 真
int i = 0;
bool flag = IsNullOrDefault(i);
标志 = 真
double d = 0.0;
Console.WriteLine(IsNullOrDefault(d));
标志 = 真
object value = 0;
Console.WriteLine(IsNullOrDefault(value));
标志 = 假
这里的对象依次包含 int,但它仍然认为它是一个对象,其默认值为 null,当前值为 0。所以它返回 False。
问题是,我重写的框架方法给了我作为对象的值,因此它将始终与上面提到的最后一个场景匹配。
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{ ....
}
根据值,我们如何将对象转换为实际类型,在这种情况下为 int?因此,即使对于上面的最后一个场景,我也会收到 True。
你必须
意识到,default
和typeof
运算符返回的值是在编译时确定的,一旦你的T
被推断为object
,你总是会得到与null
相比的值。
最好的办法是改为检查运行时类型:
protected bool IsNullOrDefault<T>(T value)
{
if (value == null)
return true;
var actualType = value.GetType();
if (actualType.IsValueType)
return value.Equals(Activator.CreateInstance(actualType));
return false;
}
object value = 0; Console.WriteLine(IsNullOrDefault(value));
在这种情况下,T
System.Object
,因此default(T)
null
。
您需要检查运行时类型而不是编译时类型来处理此问题:
public bool IsNullOrDefault(object value) {
if (value is Int32) {
return (Int32)value == 0;
} else if (value is Int64) {
return (Int64)value == 0L;
} else if …
} else {
return value == null;
}
}
涵盖您可能遇到的所有类型。
最后,
我能够通过用dynamic
类型转换值来实现这一点,
protected bool IsNullOrDefault(object obj)
{
bool retval = false;
if (obj == null)
{
retval = true;
}
else
{
retval = IsEmpty((dynamic)obj);
}
return retval;
}
protected bool IsEmpty<T>(T value)
{
return object.Equals(value, default(T));
}
在希望类型在运行时而不是编译时进行解析的位置
dynamic
应使用类型。正因为如此,在这种情况下,值 self 在不告诉它的情况下适当地确定它的类型。