例如,
我有object
类型的输入参数。我知道这个参数可以存储值类型int, float, double
(盒装值)等等。但我不知道这个方法会使用哪种值类型。我想检查盒装值类型是否为空。
喜欢这段代码:
bool IsEmpty(object boxedProperty)
{
return boxedProperty == default(typeof(boxedProperty))
}
我明白,我可以这样做:
bool IsEmpty(object boxedProperty)
{
return boxedProperty is int && boxedProperty == default(int)
|| boxedProperty is float ....
}
但它看起来像是肮脏的解决方案。这怎么样更好?
答案 0 :(得分:2)
我想这样的东西可以给你一个参考+盒装值类型的结果。
public bool IsDefaultValue(object o)
{
if (o == null)
return true;
var type = o.GetType();
return type.IsValueType && o.Equals(Activator.CreateInstance(type));
}
object i = default(int);
object j = default(float);
object k = default(double);
object s = default(string);
object i2 = (int)2;
object s2 = (string)"asas";
var bi = IsDefaultValue(i); // true
var bj = IsDefaultValue(j); // true
var bk = IsDefaultValue(k); // true
var bs = IsDefaultValue(s); // true
var bi2 = IsDefaultValue(i2); // false
var bs2 = IsDefaultValue(s2); // false
如果你是shure,你有一个值类型,那么使用这个方法:
public bool IsDefaultBoxedValueType(object o)
{
return o.Equals(Activator.CreateInstance(o.GetType()));
}
答案 1 :(得分:0)
看起来我喜欢通用功能是一个很好的方法。 类似的东西:
static void Main(string[] args)
{
object obj1 = null;
object obj2 = "Assigned value";
Console.WriteLine(string.Format("IsEmpty(obj1) --> {0}", IsEmpty(obj1)));
Console.WriteLine(string.Format("IsEmpty(obj2) --> {0}", IsEmpty(obj2)));
Console.ReadLine();
}
private static bool IsEmpty<T>(T boxedProperty)
{
T defaultProperty = default(T);
return ReferenceEquals(boxedProperty, defaultProperty);
}
输出:
IsEmpty(obj1) --> True
IsEmpty(obj1) --> False
答案 2 :(得分:0)
正如其他人指出的那样,唯一真正的方法是创建该类型的实例然后进行比较。 (另请参阅how to get the default value of a type if the type is only known as System.Type?和Default value of a type at Runtime)
您可以缓存结果,因此您只需创建默认实例1x类型。如果您必须多次拨打支票,这可以提高效率。我使用了一个静态方法和字典(它不是线程安全的),但如果你愿意,可以将它改为实例级。
static IDictionary<Type, object> DefaultValues = new Dictionary<Type, object>();
static bool IsBoxedDefault(object boxedProperty)
{
if (boxedProperty == null)
return true;
Type objectType = boxedProperty.GetType();
if (!objectType.IsValueType)
{
// throw exception or something else?? Up to how you want this to behave
return false;
}
object defaultValue = null;
if (!DefaultValues.TryGetValue(objectType, out defaultValue))
{
defaultValue = Activator.CreateInstance(objectType);
DefaultValues[objectType] = defaultValue;
}
return defaultValue.Equals(boxedProperty);
}
测试代码
static void Test()
{
Console.WriteLine(IsBoxedDefault(0)); // true
Console.WriteLine(IsBoxedDefault("")); // false (reference type)
Console.WriteLine(IsBoxedDefault(1));// false
Console.WriteLine(IsBoxedDefault(DateTime.Now)); // false
Console.WriteLine(IsBoxedDefault(new DateTime())); // true
}