如果我有一个值类型的泛型类型参数,我想知道一个值是否等于默认值我测试它是这样的:
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结构方面,我有什么不考虑的吗?
答案 0 :(得分:8)
我发现以下扩展方法很有用,适用于所有类型:
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);
}
答案 1 :(得分:3)
老问题,但接受的答案对我不起作用,所以我提交了这个(可能会更好):
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
答案 2 :(得分:1)
我需要ValueType
作为参数来简化:
static bool IsDefault(ValueType value){
var @default = Activator.CreateInstance(value.GetType());
return value.Equals(@default);
}
答案 3 :(得分:0)
旁注,我有什么不考虑的 尊重评估Nullable结构?
是的,你错过了一些东西。通过将object
作为参数,您需要调用代码框Nullable<T>
类型(将它们转换为null或其T
值)。因此,如果您传递了可空,则is/throw
会抛出,因为null
永远不会是值类型。
编辑:正如@cdhowie所说,你需要检查null。这也适用于Nullable类型。