[英]C# how to determine value wrapped within object is null or default?
我目前正在写一个自定义的必需验证属性,并且当值为null或Default时,我想返回错误。 在默认情况下,我的意思是“”表示字符串,0表示int,0.0表示double,null表示object。
为了实现这一点,我在调用以下适用于任何类型的函数
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
返回的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会在不通知我们的情况下适当地确定其类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.