首页 > 解决方案 > 运行时默认值不相等

问题描述

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

我有类似以下的东西

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

标签: c#compareboxing

解决方案


object DefaultValue(this Type type)

方法返回一个对象,虽然你在方法中判断它是否是值类型并使用Activator.CreateInstance动态创建类型。

但该值将在对象中装箱为对象类型值而不是您的预期值类型。

当您 ==在 type 的表达式上使用时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类型(做拳击)。

dymanicValint通过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# 在线


推荐阅读