C#谓词,返回盒装值类型是否为该类型的默认值

时间:2011-07-07 15:41:07

标签: c# boxing

是否可以创建一个采用盒装值类型的方法,并返回该值类型是否等于该类型的默认值?

所以我想创建一个带有以下签名的方法:

bool IsDefault(object boxedValueType);

注意:以下代码无效,因为T设置为object,因此default(T)始终为null

bool IsDefault<T>(T input)
{
    return Equals(input, default(T));
}

6 个答案:

答案 0 :(得分:2)

使用反射,但这是一种缓慢的方法

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("1 = " + IsDefault(1));
        Console.WriteLine("0 = " + IsDefault(default(int)));

        Console.WriteLine("1.0 = " + IsDefault(1.0));
        Console.WriteLine("0.0 = " + IsDefault(default(double)));

        Console.WriteLine("Today = " + IsDefault(DateTime.Today));
        Console.WriteLine("1.1.1 = " + IsDefault(default(DateTime)));

        //Console.WriteLine(IsDefault(""));
        //Console.WriteLine(IsDefault(default(string)));

        Console.ReadKey();
    }

    static bool IsDefault(object boxedValueType)
    {
        if (boxedValueType == null) throw new ArgumentNullException("boxedValueType");

        var t = boxedValueType.GetType();
        if (!t.IsValueType) throw new ArgumentOutOfRangeException("boxedValueType");

        object def = Activator.CreateInstance(t);
        return boxedValueType.Equals(def);
    }
}

答案 1 :(得分:1)

您可能更适合使用可空类型而不是盒装默认值。对null进行测试很容易,而可空类型通常是比特殊值更清晰的设计决策。

答案 2 :(得分:1)

您可以使用反射来获取该类型的默认值。有关通过反射获取默认值的信息,请参阅this question。通过调用该函数将您的调用替换为默认值(T):

return input.Equals(GetDefault(input.GetType());

答案 3 :(得分:1)

使用反射,您可以使用值的类型调用泛型方法:

public static bool IsDefault(object value)
{
    if (value == null)
    {
        throw new ArgumentNullException("value");
    }
    return (bool)typeof(Program).GetMethod("IsDefaultGeneric")
                                .MakeGenericMethod(value.GetType())
                                .Invoke(null, new object[] { value });
}

public static bool IsDefaultInternal<T>(T value)
    where T : struct, IEquatable<T>
{
    return value.Equals(default(T));
}

答案 4 :(得分:1)

代码+单元测试,它将告诉您盒装或未装箱的对象是否为其默认值。还包括通用版本。

    [Test]
    public void BoxedIntIsDefault()
    {
        Assert.That(IsDefault((object)0), Is.True);
        Assert.That(IsDefault((object)1), Is.False);
        Assert.That(IsDefault<object>(0), Is.True);
        Assert.That(IsDefault<object>(1), Is.False);

    }
    bool IsDefault(object obj)
    {
        return Equals(obj, GetDefault(obj.GetType()));                
    }

    bool IsDefault<T>(T input)
    {
        return Equals(input, GetDefault(input.GetType()));
    }

    public static object GetDefault(Type type)
    {
        if (type.IsValueType)
        {
            return Activator.CreateInstance(type);
        }
        return null;
    }

答案 5 :(得分:0)

如果你只想使用默认值的默认构造函数,它可以是

bool IsDefault<T>(T input)
{
    return EqualityComparer<T>.Default.Equals(value, Activator.CreateInstance<T>());
}