私がそのような構造を持っているとしましょう
public class Form
{
#region Public Properties
public List<Field> Fields { get; set; }
public string Id { get; set; }
public string Name { get; set; }
public string Version { get; set; }
public int Revision { get; set; }
#endregion
}
クラスForm
にはフィールドのリストが含まれているため、フィールド自体がそのような構造で表されているとしましょう
public class Field
{
#region Public Properties
public string DisplayName { get; set; }
public List<Field> Fields { get; set; }
public string Id { get; set; }
public FieldKind Type { get; set; }
public FieldType FieldType { get; set; }
#endregion
}
これField
は基本的に複合構造であり、それぞれField
に子フィールドのリストが含まれています。したがって、構造は階層的です。また、フィールドにはFieldType
クラスへの参照があります。
public class FieldType
{
#region Public Properties
public DataType DataType { get; set; }
public string DisplayName { get; set; }
public string Id { get; set; }
#endregion
}
そして最後に、DataType
public class DataType
{
#region Public Properties
public string BaseType { get; set; }
public string Id { get; set; }
public string Name { get; set; }
public List<Restriction> Restrictions { get; set; }
#endregion
}
私が達成したいのは、そのような複雑な構造の違いを取得することです。たとえば、ある種のComparerがあれば、フォーム全体の構造化された違いが1つのクラスとして得られるとしましょう。私が構造的な違いと言ったのは、そのようなものであるべきだという意味です。
- フィールドの違い
Form
(出力Form
はバージョン フィールドに違いがあります (色が異なります) Fields
フィールドから編集済みフィールドまでの階層を含む、コレクションの相違点FieldType
との同じ動作DataType
- への の削除と追加を検出
Field
しますForm
(したがって、おそらく各差分にはタイプがあります)
私が今持っているもの。私は一般的なアプローチから始め、IEqualityComparer インターフェイスを実装する ReflectionComparer を使用しようとしました
public bool Equals(T x, T y)
{
var type = typeof(T);
if (typeof(IEquatable<T>).IsAssignableFrom(type))
{
return EqualityComparer<T>.Default.Equals(x, y);
}
var enumerableType = type.GetInterface(typeof(IEnumerable<>).FullName);
if (enumerableType != null)
{
var elementType = enumerableType.GetGenericArguments()[0];
var elementComparerType = typeof(DifferenceComparer<>).MakeGenericType(elementType);
var elementComparer = Activator.CreateInstance(elementComparerType, new object[] { _foundDifferenceCallback, _existedDifference });
return (bool)typeof(Enumerable).GetGenericMethod("SequenceEqual", new[] { typeof(IEnumerable<>), typeof(IEnumerable<>), typeof(IEqualityComparer<>) }).MakeGenericMethod(elementType).Invoke(null, new[] { x, y, elementComparer });
}
foreach (var propertyInfo in type.GetProperties())
{
var leftValue = propertyInfo.GetValue(x);
var rightValue = propertyInfo.GetValue(y);
if (leftValue != null)
{
var propertyComparerType = typeof(DifferenceComparer<>).MakeGenericType(propertyInfo.PropertyType);
var propertyComparer = Activator.CreateInstance(propertyComparerType, new object[] {_foundDifferenceCallback, _existedDifference});
if (!((bool)typeof(IEqualityComparer<>).MakeGenericType(propertyInfo.PropertyType)
.GetMethod("Equals")
.Invoke(propertyComparer, new object[] { leftValue, rightValue })))
{
// Create and publish the difference with its Type
}
}
else
{
if (!Equals(leftValue, rightValue))
{
// Create and publish the difference with its Type
}
}
}
//return true if no differences are found
}
そしてDifference
クラス
public struct Difference
{
public readonly string Property;
public readonly DifferenceType Type;
public readonly IExtractionable Expected;
public readonly IExtractionable Actual;
}
しかし、おそらくそれは私が行きたい方法ではありません。なぜなら、各フィールドにはIDがあり、フォームごとに異なる可能性があることを考慮して、フィールドをより正確に比較する必要があり、比較プロセスをより制御したいからです。私にとっては、差分ツールのように聞こえます。
だから私は、違いを簡単に視覚化できるクライアントコードに公開するための良いパターンとかなり良い構造を探していますか?