运行时默认值等于失败

时间:2018-08-25 18:31:20

标签: c# compare boxing

我想在运行时对成员属性进行一些比较,但是值类型禁止异常行为。

我有类似以下内容

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。是因为现在它正在比较对象或什么。我可以实现我想要的行为吗?

1 个答案:

答案 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); 

c# online


以下是您的案例的样本

我们可以看到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

c# online