如何检查.NET中的盒装值是否为空

时间:2016-10-21 10:31:49

标签: c# .net object reflection backend

例如,

我有object类型的输入参数。我知道这个参数可以存储值类型int, float, double(盒装值)等等。但我不知道这个方法会使用哪种值类型。我想检查盒装值类型是否为空。

喜欢这段代码:

bool IsEmpty(object boxedProperty)
{
    return boxedProperty == default(typeof(boxedProperty))
}

我明白,我可以这样做:

bool IsEmpty(object boxedProperty)
{
    return boxedProperty is int && boxedProperty == default(int)
    || boxedProperty is float ....
}

但它看起来像是肮脏的解决方案。这怎么样更好?

3 个答案:

答案 0 :(得分:2)

我想这样的东西可以给你一个参考+盒装值类型的结果。

public bool IsDefaultValue(object o)
{
    if (o == null)
        return true;

    var type = o.GetType();
    return type.IsValueType && o.Equals(Activator.CreateInstance(type));
}

object i = default(int);
object j = default(float);
object k = default(double);
object s = default(string);

object i2 = (int)2;
object s2 = (string)"asas";


var bi = IsDefaultValue(i); // true
var bj = IsDefaultValue(j); // true
var bk = IsDefaultValue(k); // true
var bs = IsDefaultValue(s); // true

var bi2 = IsDefaultValue(i2); // false
var bs2 = IsDefaultValue(s2); // false

如果你是shure,你有一个值类型,那么使用这个方法:

public bool IsDefaultBoxedValueType(object o)
{
    return o.Equals(Activator.CreateInstance(o.GetType()));
}

答案 1 :(得分:0)

看起来我喜欢通用功能是一个很好的方法。 类似的东西:

    static void Main(string[] args)
    {
        object obj1 = null;
        object obj2 = "Assigned value";

        Console.WriteLine(string.Format("IsEmpty(obj1) --> {0}", IsEmpty(obj1)));
        Console.WriteLine(string.Format("IsEmpty(obj2) --> {0}", IsEmpty(obj2)));

        Console.ReadLine();
    }

    private static bool IsEmpty<T>(T boxedProperty)
    {
        T defaultProperty = default(T);
        return ReferenceEquals(boxedProperty, defaultProperty);
    }

输出:

IsEmpty(obj1) --> True
IsEmpty(obj1) --> False

答案 2 :(得分:0)

正如其他人指出的那样,唯一真正的方法是创建该类型的实例然后进行比较。 (另请参阅how to get the default value of a type if the type is only known as System.Type?Default value of a type at Runtime

您可以缓存结果,因此您只需创建默认实例1x类型。如果您必须多次拨打支票,这可以提高效率。我使用了一个静态方法和字典(它不是线程安全的),但如果你愿意,可以将它改为实例级。

static IDictionary<Type, object> DefaultValues = new Dictionary<Type, object>();
static bool IsBoxedDefault(object boxedProperty)
{
    if (boxedProperty == null)
        return true;
    Type objectType = boxedProperty.GetType();

    if (!objectType.IsValueType)
    {
        // throw exception or something else?? Up to how you want this to behave
        return false;
    }

    object defaultValue = null;
    if (!DefaultValues.TryGetValue(objectType, out defaultValue))
    {
        defaultValue = Activator.CreateInstance(objectType);
        DefaultValues[objectType] = defaultValue;
    }
    return defaultValue.Equals(boxedProperty);
}

测试代码

static void Test()
{
    Console.WriteLine(IsBoxedDefault(0)); // true
    Console.WriteLine(IsBoxedDefault("")); // false (reference type)
    Console.WriteLine(IsBoxedDefault(1));// false
    Console.WriteLine(IsBoxedDefault(DateTime.Now)); // false
    Console.WriteLine(IsBoxedDefault(new DateTime())); // true
}