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

C# 如何确定对象中包装的值为 null 或默认值

你必须

意识到,defaulttypeof运算符返回的值是在编译时确定的,一旦你的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 在不告诉它的情况下适当地确定它的类型。