返回一个盒装值类型是否为该类型的默认值的c#谓词
本文关键字:类型 是否 默认值 谓词 盒装 一个 返回 | 更新日期: 2023-09-27 18:01:33
是否有可能创建一个方法,该方法接受盒装值类型并返回该值类型是否等于该类型的默认值?
所以我想创建一个签名如下的方法:bool IsDefault(object boxedValueType);
注意:当T被设置为类型object
时,以下代码将不起作用,因此default(T)
将始终是null
。
bool IsDefault<T>(T input)
{
return Equals(input, default(T));
}
使用反射,但这是一个缓慢的方法
class Program
{
static void Main(string[] args)
{
Console.WriteLine("1 = " + IsDefault(1));
Console.WriteLine("0 = " + IsDefault(default(int)));
Console.WriteLine("1.0 = " + IsDefault(1.0));
Console.WriteLine("0.0 = " + IsDefault(default(double)));
Console.WriteLine("Today = " + IsDefault(DateTime.Today));
Console.WriteLine("1.1.1 = " + IsDefault(default(DateTime)));
//Console.WriteLine(IsDefault(""));
//Console.WriteLine(IsDefault(default(string)));
Console.ReadKey();
}
static bool IsDefault(object boxedValueType)
{
if (boxedValueType == null) throw new ArgumentNullException("boxedValueType");
var t = boxedValueType.GetType();
if (!t.IsValueType) throw new ArgumentOutOfRangeException("boxedValueType");
object def = Activator.CreateInstance(t);
return boxedValueType.Equals(def);
}
}
您可以使用反射来获取该类型的默认值。请参阅关于通过反射获取默认值的问题。将对default(T)的调用替换为对该函数的调用:
return input.Equals(GetDefault(input.GetType());
使用反射,您可以使用值的类型调用泛型方法:
public static bool IsDefault(object value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
return (bool)typeof(Program).GetMethod("IsDefaultGeneric")
.MakeGenericMethod(value.GetType())
.Invoke(null, new object[] { value });
}
public static bool IsDefaultInternal<T>(T value)
where T : struct, IEquatable<T>
{
return value.Equals(default(T));
}
您可能更适合使用可空类型而不是盒装默认值。对null
进行测试很容易,可空类型通常是比特殊值更干净的设计决策。
代码+单元测试,它将告诉您盒装或未盒装对象是否是其默认值。还包括通用版本。
[Test]
public void BoxedIntIsDefault()
{
Assert.That(IsDefault((object)0), Is.True);
Assert.That(IsDefault((object)1), Is.False);
Assert.That(IsDefault<object>(0), Is.True);
Assert.That(IsDefault<object>(1), Is.False);
}
bool IsDefault(object obj)
{
return Equals(obj, GetDefault(obj.GetType()));
}
bool IsDefault<T>(T input)
{
return Equals(input, GetDefault(input.GetType()));
}
public static object GetDefault(Type type)
{
if (type.IsValueType)
{
return Activator.CreateInstance(type);
}
return null;
}
如果您只想使用默认构造函数作为默认值,则可以使用
bool IsDefault<T>(T input)
{
return EqualityComparer<T>.Default.Equals(value, Activator.CreateInstance<T>());
}