サーバーからオブジェクト(作成したカスタムタイプ)を受け取り、ユーザーがオブジェクトを編集してから、「チェンジセット」をサーバーに送信するWindowsストアアプリを作成しています。この変更セットは、ユーザーが編集したフィールドを除くすべてのフィールドが null に設定された、受信したオブジェクトと同じタイプのオブジェクトです。これらのフィールドには、ユーザーの編集が次のように含まれます。
オリジナルケース: 説明:「ひびの入った排気管」 ステータス:「オープン」 お客様: "" マイレージ: 10000 編集されたケース: 説明: "" ステータス「オープン」 お客様:「株式会社例」 マイレージ: 10000 ケースチェンジセット: 説明: "" ステータス: null お客様:「株式会社例」 マイレージ: null
アプリが最初にサーバーからオブジェクトをダウンロードするときに、後で比較するためにオブジェクトのコピーを作成します。次に、ユーザーがオブジェクトの 1 つに変更を加え、ユーザーが変更を送信すると、これら 2 つのオブジェクトの変更セットがジェネリック メソッドで計算されますCalculateChangeSet
。2 つのオブジェクトのすべてのプロパティを調べて、等しいかどうかを比較します。
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;
}
このメソッドは、リストを除くすべてのプロパティで正常に機能するため、リストを処理する if 句を作成しました。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?)
それを使用して新しいリストを作成しようとすると、エラーが発生するのはなぜですか? この問題にアプローチするより良い方法があれば、私は提案を受け付けています..