Сравнение стоимости имущества в двух случаях - PullRequest
0 голосов
/ 20 марта 2012

Я думаю, у меня проблемы с боксом

foreach(var p in item.GetType().GetProperties().
    Where(p => p.GetValue(original, null) is ValueType))
{
    var originalValue = p.GetValue(original, null);
    var modifiedValue = p.GetValue(item, null);
    if (!originalValue.Equals(modifiedValue)) 
        kvpData.AppendFormat("{0}={1}&", p.Name, originalValue);
}

originalValue никогда не равно modifiedValue, я предполагаю, что это потому, что они заключены в объекты внутри Object.Но как мне это исправить?

Ответы [ 3 ]

1 голос
/ 20 марта 2012

Это не проблема бокса. Equals - это виртуальный метод, который в штучной форме переопределяет типы значений.

Однако я не уверен, в чем проблема. Может ли быть так, что на самом деле нет подходящих свойств? Помните, что GetProperties() без каких-либо параметров вернет только public properties. Если вам нужны private свойства, вам нужно добавить BindingFlags:

GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)

(я предполагаю, что вам не нужны статические свойства.)

Вы также уверены, что на самом деле вам нужны свойства , а не поля ? Помните, что если вы объявите что-то как

public string Name;

тогда это поле , тогда как

public string Name { get; set; }

является свойством . Если вам нужны именно эти поля, вам нужно использовать GetFields() вместо GetProperties() с такими же флагами привязки.

0 голосов
/ 20 марта 2012

Linq - отличный инструмент, но я не уверен, почему вы используете его здесь.Вы фактически заставляете набор свойств повторяться дважды, что очень дорого.Я бы написал код без Linq.Кроме того, нет необходимости получать значение более одного раза, что опять-таки очень дорого.Попробуйте этот код.Это позволяет избежать недостатков, на которые я указывал, и правильно сравнивал их при создании и тестировании фиктивного класса:

    foreach(PropertyInfo p in item.GetType().GetProperties())
    {
        if (p.PropertyType.BaseType == typeof(ValueType) || p.PropertyType == typeof(string))
        {
            var originalValue = p.GetValue(original, null);
            var modifiedValue = p.GetValue(item, null);
            if (originalValue != modifiedValue) kvpData.AppendFormat("{0}={1}&", p.Name, originalValue);
        }
     } 

Кроме того, обратите внимание, что строки не являются типом ValueType, хотя они и реализуют сравнение значений.

0 голосов
/ 20 марта 2012

С MSDN: Object.Equals :

Реализация по умолчанию Equals поддерживает ссылочное равенство для ссылочные типы и битовое равенство для типов значений. Ссылка равенство означает, что ссылки на объекты, которые сравниваются, относятся к тот же объект. Побитовое равенство означает, что сравниваемые объекты имеют то же двоичное представление.

Это означает, что в вашем случае эти 2 объекта (если они являются ссылочными типами) никогда не указывают на один и тот же экземпляр.

Нет простого способа решить эту проблему в общем виде, как вы хотели бы.

Но вы можете реализовать ( только пример ) IComparable для тех типов, которые вы хотите сравнить, и после этой итерации проверьте, реализует ли тип значения rturned этот интерфейс так что приведите и вызовите это реализовано IComparable.CompareTo метод.

Вы можете проверить, реализует ли объект указанное взаимодействие, в этом текущем случае IComparable вы можете сделать что-то вроде этого:

originalValue .GetType().GetInterfaces().Any(x =>
  x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IComparable))

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...