我想在运行时对成员属性进行一些比较,但是值类型禁止异常行为。
我有类似以下内容
public static object DefaultValue(this Type type)
{
return type.IsValueType ? Activator.CreateInstance(type) : null;
}
class ExampleClass
{
public string Id { get; set; }
public string Title { get; set; }
public decimal Price { get; set; }
public XElement ToXml()
{
var srcTree = from prop in GetType().GetProperties()
let value = prop.GetValue(foo, null)
where value != prop.PropertyType.DefaultValue()
select new XElement(prop.Name.ToLower(), value);
...
}
}
如果我初始化对象new ExampleClass()
,则会发现价格值为0。我可以确认DefaultValue()
对于相等比较期间不等于0的价格返回0。是因为现在它正在比较对象或什么。我可以实现我想要的行为吗?
答案 0 :(得分:3)
object DefaultValue(this Type type)
该方法返回一个对象,尽管您判断该方法是否为值类型并使用Activator.CreateInstance
动态创建该类型。
但是该值将在一个对象中装箱,而不是您的期望值类型。
在类型==
的表达式上使用object
时,它将使用ReferenceEquals
比较引用而不是值。
var srcTree = from prop in GetType().GetProperties()
let value = prop.GetValue(foo, null)
where !Equals(value, prop.PropertyType.DefaultValue())
select new XElement(prop.Name.ToLower(), value);
以下是您的案例的样本
我们可以看到defaultVal
对象设置了一个0
类型的值int
(正在装箱)。
dymanicVal
通过int
方法创建了Activator.CreateInstance
。
然后,当我们使用==
比较两个对象时,它们将比较其引用而不是int
值
因此您可以尝试使用Equals方法比较该值,将调用RuntimeHelpers.Equals方法,然后比较其值而不是引用。
object defaultVal = 0;
object dymanicVal = Activator.CreateInstance(typeof(int));
Console.WriteLine(Equals(defaultVal, dymanicVal)); //True
Console.WriteLine(defaultVal == dymanicVal); //false