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)
如果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)
将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)