Я пишу приложение магазина Windows, которое получает объект (настраиваемый тип, который я создал) с сервера, позволяет пользователю редактировать объект, а затем отправляет «набор изменений» обратно на сервер. Этот набор изменений - это просто объект того же типа, что и полученный объект, с каждым полем, установленным в null, за исключением полей, редактируемых пользователем. Эти поля затем содержат изменения пользователя следующим образом:Вычислить набор изменений для объекта
Original Case: Description: "Cracked exhaust pipe" Status: "Open" Customer: "" Mileage: 10000 Edited Case: Description: "" Status "Open" Customer: "Example inc." Mileage: 10000 Case changeset: Description: "" Status: null Customer: "Example inc." Mileage: null
Когда приложение первое загружает объект с сервера я сделать копию для последующего сравнения. Затем пользователь вносит изменения в один из объектов, и когда пользователь отправляет свои изменения, набор изменений этих двух объектов вычисляется с помощью общего метода CalculateChangeSet
. Он проходит через каждое свойство двух объектов и сравнивает их равенства:
public static T CalculateChangeSet<T>(T oldObject, T newObject) where T : new()
{
T changeSet = (T)Activator.CreateInstance(oldObject.GetType());
foreach (PropertyInfo property in oldObject.GetType().GetRuntimeProperties())
{
var oldValue = property.GetValue(oldObject);
var newValue = newObject.GetType().GetRuntimeProperty(property.Name).GetValue(newObject);
if (oldValue != null && newValue != null)
{
if (oldValue is IList)
{
Type listType = oldValue.GetType().GetRuntimeProperty("Item").PropertyType;
IList<listType> oldList = (IList<listType>)oldValue; //Visual studio complains about
IList<listType> newList = (IList<listType>)newValue; //listType not being found
if (!oldList.SequenceEqual(newList))
{
changeSet.GetType().GetRuntimeProperty(property.Name).SetValue(changeSet, newValue, null);
}
}
else
{
if (!oldValue.Equals(newValue))
{
changeSet.GetType().GetRuntimeProperty(property.Name).SetValue(changeSet, CalculateChangeSet(oldValue, newValue));
}
}
}
else
{
changeSet.GetType().GetRuntimeProperty(property.Name).SetValue(changeSet, newValue);
}
}
return changeSet;
}
Метод штрафа для каждого свойства, я сталкивался за исключением списков работает, так что я создал, если условие, чтобы иметь дело со списками. Поскольку list1.Equals(list2)
не сравнивает элементы в списках, нам нужно сделать oldValue
и newValue
до List<T>
, чтобы иметь возможность использовать list.SequenceEqual()
.
Почему я получаю сообщение об ошибке The type or namespace name 'listType' could not be found (are you missing a using directive or an assembly reference?)
, когда я пытаюсь использовать его для создания новых списков? Если есть лучший способ подойти к этой проблеме я открыт для предложений ..
[ 'SequenceEqual' не принимает необщего' значения IEnumerable'] (http://msdn.microsoft.com/en-gb/library/bb348567 .aspx). – shambulator
И не только это, но класс, реализующий 'IList', не обязательно реализует 'IList'. Хотя это можно преодолеть, используя 'IEnumerable' вместо' IList'. –
shambulator
решение отражения не работает .. GetMethod не существует в структуре хранилища окон, но GetRuntimeMethod делает. Однако GetRuntimeMethod требует наличия массива типов в качестве второго параметра, поэтому он возвращался к исходной проблеме (не имея возможности использовать listType). Я, однако, использовал слегка измененную версию вашего NonGenericSequenceEqual, поэтому спасибо за это – jbb