检索“默认”值的通用扩展方法?

时间:2013-09-30 23:15:47

标签: c# generics extension-methods

根据以下示例,确定对象的默认值,我正在玩一下:

https://stackoverflow.com/a/3195792/1293496

为System.Type创建了此特定扩展方法。我想要完成的是让它更加通用,我可以做这样的事情:

int i = 3;
bool amIaDefaultValue = i.IsDefaultValue();

如果i == 0(int的默认值),我希望这会返回true,所有其他实例都是false。

这是我最初的尝试:

public static bool IsDefaultValue<T>(this T value)
{
    var t = typeof(T); // always comes back as object..?

    if (t.IsValueType && Nullable.GetUnderlyingType(t) == null)
    {
        return value.Equals(Activator.CreateInstance<T>());
    }
    else
    {
        var defaultValue = default(T);

        if (value == null)
            return defaultValue == null;
        else
            return value.Equals(defaultValue);
    }
}

从好的方面来说,我可以将.IsDefaultValue()附加到任何对象上。不幸的是,T的类型总是以System.Object的形式返回。如果我这样设置,我可以得到正确的类型:

var t = typeof(value);

但如果该值恰好为null,我会马上得到一个错误。有没有一个很好的解决方法来实现这样的扩展方法?或者我应该坚持从示例中经过试验和测试的路线?

修改 正如评论所指出的那样,我似乎过度简化了这一点并错过了问题的根源。这是实际调用我的IsDefaultValue():

foreach (var imprintProperty in deltas.GetType().GetProperties())
{
    var value = imprintProperty.GetValue(deltas);
    if (!value.IsDefaultValue())
    {
        // get corresponding prop in programmable area
        var programmableProp = progarea.GetType().GetProperty(imprintProperty.Name);
        if (programmableProp != null)
            programmableProp.SetValue(progarea, value);
    }
}

现在很明显,.GetValue总是作为System.Object返回。 UFF。

是否仍然可以将对象视为扩展方法中的基础类型?很抱歉与此混淆。

1 个答案:

答案 0 :(得分:0)

看看这个:

static class Program
{
    static void Main()
    {
        int a = 1;

        Console.WriteLine("a.IsDefaultValue() : " + a.IsDefaultValue());

        a = 0;

        Console.WriteLine("a.IsDefaultValue() : " + a.IsDefaultValue());

        object obj = new object();

        Console.WriteLine("obj.IsDefaultValue() : " + obj.IsDefaultValue());

        obj = null;

        Console.WriteLine("obj.IsDefaultValue() : " + obj.IsDefaultValue());

        int? b = 1;

        Console.WriteLine("b.IsDefaultValue() : " + b.IsDefaultValue());

        b = null;

        Console.WriteLine("b.IsDefaultValue() : " + b.IsDefaultValue());

        Console.ReadKey(true);
    }

    static bool IsDefaultValue<T>(this T value)
    {
        if (ReferenceEquals(value, null))
        {
            return true;
        }

        var t = value.GetType();

        if (t.IsValueType)
        {
            return value.Equals(Activator.CreateInstance(value.GetType()));
        }

        return false;
    }
}

显然有效(我要说我相信另一种方式应该有效但不是)