значения по умолчанию во время выполнения не соответствуют равенству - PullRequest
0 голосов
/ 25 августа 2018

Я хочу сделать некоторое сравнение свойств элемента во время выполнения, но тип значения запрещает необычное поведение.

У меня есть что-то вроде следующего

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 голосов
/ 25 августа 2018
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 создан int методом Activator.CreateInstance.

Затем, когда мы используем == для сравнения двух объектов, они будут сравниватьих ссылка вместо int value

, так что вы можете попытаться использовать метод 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

...