检查给定对象(引用或值类型)是否等于其默认值

Bri*_*ian 24 c# generics default-value

我试图找到一种方法来检查并查看给定对象的值是否等于其默认值.我环顾四周,想出了这个:

    public static bool IsNullOrDefault<T>(T argument)
    {
        if (argument is ValueType || argument != null)
        {
            return object.Equals(argument, default(T));
        }
        return true;
    }
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是我想这样称呼它:

            object o = 0;
            bool b = Utility.Utility.IsNullOrDefault(o);
Run Code Online (Sandbox Code Playgroud)

是o是一个对象,但我想让它弄清楚基类型并检查它的默认值.在这种情况下,基类型是一个整数,我想在这种情况下知道该值是否等于default(int),而不是default(object).

我开始认为这可能是不可能的.

Ant*_*ram 33

在您的示例中,您的整数是盒装的,因此您T将是object,并且对象的默认值为null,因此这对您没有价值.如果对象是值类型,则可以获取它的一个实例(这将是默认值)以用作比较.就像是:

if (argument is ValueType)
{
   object obj = Activator.CreateInstance(argument.GetType());
   return obj.Equals(argument);
}
Run Code Online (Sandbox Code Playgroud)

在诉诸于此之前,你想要处理其他可能性.Marc Gravell的回答提出了一些需要考虑的好点,但对于你的方法的完整版本,你可能会有

public static bool IsNullOrDefault<T>(T argument)
{
    // deal with normal scenarios
    if (argument == null) return true;
    if (object.Equals(argument, default(T))) return true;

    // deal with non-null nullables
    Type methodType = typeof(T);
    if (Nullable.GetUnderlyingType(methodType) != null) return false;

    // deal with boxed value types
    Type argumentType = argument.GetType();
    if (argumentType.IsValueType && argumentType != methodType) 
    {
        object obj = Activator.CreateInstance(argument.GetType());
        return obj.Equals(argument);
    }

    return false;
}
Run Code Online (Sandbox Code Playgroud)

  • 实现此目标的另一种方法是将其编码为扩展:`public static bool IsNullOrDeafult &lt;T&gt;(此T参数)` (2认同)

Mar*_*ell 7

如果o为null,则在非泛型(object)方法中,您将无法访问原始类型 - 并且您无法做很多事情.

因此,唯一重要的是不可空的值类型,因此:

Type type = value.GetType();
if(!type.IsValueType) return false; // can't be, as would be null
if(Nullable.GetUnderlyingType(type) != null) return false; // ditto, Nullable<T>
object defaultValue = Activator.CreateInstance(type); // must exist for structs
return value.Equals(defaultValue);
Run Code Online (Sandbox Code Playgroud)


Evo*_*lor 5

将Anthony Pegram 的答案转换为扩展方法:

using System;

//Adapted from /sf/answers/458729351/
public static class ObjectExtensions
{
    public static bool IsNullOrDefault<TObject>(this TObject argument)
    {
        // deal with normal scenarios
        if (argument == null)
        {
            return true;
        }
        if (object.Equals(argument, default(TObject)))
        {
            return true;
        }

        // deal with non-null nullables
        Type methodType = typeof(TObject);
        if (Nullable.GetUnderlyingType(methodType) != null)
        {
            return false;
        }

        // deal with boxed value types
        Type argumentType = argument.GetType();
        if (argumentType.IsValueType && argumentType != methodType)
        {
            object obj = Activator.CreateInstance(argument.GetType());
            return obj.Equals(argument);
        }

        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用语法:

myVariable.IsNullOrDefault();
Run Code Online (Sandbox Code Playgroud)