如何通过反射获取 ValueType 类型的默认值

发布于 2024-11-29 19:41:35 字数 581 浏览 1 评论 0原文

如果我有一个值类型的泛型类型参数,并且我想知道某个值是否等于默认值,我会像这样测试它:

static bool IsDefault<T>(T value){
    where T: struct
    return value.Equals(default(T));
}

如果我没有泛型类型参数,那么似乎我必须使用反射。如果该方法必须适用于所有值类型,那么有没有比我在这里所做的更好的方法来执行此测试? :

static bool IsDefault(object value){
   if(!(value is ValueType)){
      throw new ArgumentException("Precondition failed: Must be a ValueType", "value");
   }
   var @default = Activator.CreateInstance(value.GetType());
   return value.Equals(@default);  
}

顺便说一句,关于评估 Nullable 结构,我在这里没有考虑什么吗?

If I have a generic type parameter that is a value type and I want to know if a value is equal to the default I test it like this:

static bool IsDefault<T>(T value){
    where T: struct
    return value.Equals(default(T));
}

If I don't have a generic type parameter, then it seems like I would have to use reflection. If the method has to work for all value types, then Is there a better way to perform this test than what I am doing here? :

static bool IsDefault(object value){
   if(!(value is ValueType)){
      throw new ArgumentException("Precondition failed: Must be a ValueType", "value");
   }
   var @default = Activator.CreateInstance(value.GetType());
   return value.Equals(@default);  
}

On a side note, Is there anything I am not considering here with respect to evaluating Nullable structs?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

祁梦 2024-12-06 19:41:35

我发现以下扩展方法很有用并且适用于所有类型:

public static object GetDefault(this Type t)
{
    return t.IsValueType ? Activator.CreateInstance(t) : null;
}

public static T GetDefault<T>()
{
    var t = typeof(T);
    return (T) GetDefault(t);
}

public static bool IsDefault<T>(T other)
{
    T defaultValue = GetDefault<T>();
    if (other == null) return defaultValue == null;
    return other.Equals(defaultValue);
}

I have found the following extension methods useful and will work for all types:

public static object GetDefault(this Type t)
{
    return t.IsValueType ? Activator.CreateInstance(t) : null;
}

public static T GetDefault<T>()
{
    var t = typeof(T);
    return (T) GetDefault(t);
}

public static bool IsDefault<T>(T other)
{
    T defaultValue = GetDefault<T>();
    if (other == null) return defaultValue == null;
    return other.Equals(defaultValue);
}
也只是曾经 2024-12-06 19:41:35

老问题,但接受的答案对我不起作用,所以我提交这个(可能可以做得更好):

public static object GetDefault(this Type type)
{   
    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
        var valueProperty = type.GetProperty("Value");
        type = valueProperty.PropertyType;
    }

    return type.IsValueType ? Activator.CreateInstance(type) : null;
}

结果如下:

typeof(int).GetDefault();       // returns 0
typeof(int?).GetDefault();      // returns 0
typeof(DateTime).GetDefault();  // returns 01/01/0001 00:00:00
typeof(DateTime?).GetDefault(); // returns 01/01/0001 00:00:00
typeof(string).GetDefault();    // returns null
typeof(Exception).GetDefault(); // returns null

Old question but the accepted answer doesn't work for me so I submit this (probably can be made better):

public static object GetDefault(this Type type)
{   
    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
        var valueProperty = type.GetProperty("Value");
        type = valueProperty.PropertyType;
    }

    return type.IsValueType ? Activator.CreateInstance(type) : null;
}

With the following results:

typeof(int).GetDefault();       // returns 0
typeof(int?).GetDefault();      // returns 0
typeof(DateTime).GetDefault();  // returns 01/01/0001 00:00:00
typeof(DateTime?).GetDefault(); // returns 01/01/0001 00:00:00
typeof(string).GetDefault();    // returns null
typeof(Exception).GetDefault(); // returns null
ゃ懵逼小萝莉 2024-12-06 19:41:35

我需要 ValueType 作为参数来简化:

static bool IsDefault(ValueType value){
   var @default = Activator.CreateInstance(value.GetType());
   return value.Equals(@default);  
}

I would require ValueType as the parameter to simplify:

static bool IsDefault(ValueType value){
   var @default = Activator.CreateInstance(value.GetType());
   return value.Equals(@default);  
}
烟花易冷人易散 2024-12-06 19:41:35

顺便说一句,有什么我没有考虑的吗?
关于评估 Nullable 结构?

是的,你错过了一些东西。通过将 object 作为参数,您需要调用代码来框 Nullable 类型(将它们转换为 null 或 T 值)。因此,如果您传递可为 null 的值,您的 is/throw 将抛出异常,因为 null 永远不会是值类型。

编辑:正如@cdhowie所说,您需要检查是否为空。这也适用于可为 Null 的类型。

On a side note, Is there anything I am not considering here with
respect to evaluating Nullable structs?

Yes, you are missing something. By taking an object as the parameter in you are requiring calling code to box Nullable<T> types (which converts them to null or to their T Value). So if you pass a nullable, your is/throw will throw because null will never be a value type.

Edit: As @cdhowie said, you'll need to check for null. This will work for Nullable types as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文