我想在运行时对成员属性进行一些比较,但值类型禁止异常行为。
我有如下内容
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。是因为现在它是比较对象还是什么。我怎样才能实现我想要的行为?
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);
C# 在线
这是您的案例示例
我们可以看到defaultVal
对象设置了一个值0
,这是int
类型(做装箱(。
dymanicVal
通过Activator.CreateInstance
方法创建int
。
然后,当我们使用==
比较两个对象时,它们将比较它们的引用而不是int
值
所以你可以尝试使用Equals方法来比较值将调用RuntimeHelpers.Equals方法然后比较它们的值而不是引用。
object defaultVal = 0;
object dymanicVal = Activator.CreateInstance(typeof(int));
Console.WriteLine(Equals(defaultVal, dymanicVal)); //True
Console.WriteLine(defaultVal == dymanicVal); //false
C# 在线