単体テストのための簡単な汎用比較器をまとめています。
IComparableインターフェイスを使用したくないのは、それを実装する必要があるクラスがあまりにも多く、ユニットテストでのみ使用されるため、リフレクションのパフォーマンスに問題はありません。リフレクションを使用した一般的な比較者
は、これまでのところ私はこれを持っている:
public IEnumerable<NonEqualProperty> Compare<T>(T first, T second) where T : class
{
var list = new List<NonEqualProperty>();
var type = first.GetType();
var properties = type.GetProperties();
var basicTypes = properties.Where(p => !p.PropertyType.IsClass && !p.PropertyType.IsInterface
|| p.PropertyType == typeof(string));
foreach (var prop in basicTypes)
{
var value1 = prop.GetValue(first, null);
var value2 = prop.GetValue(second, null);
if (value1 != null && value2 != null && value1.Equals(value2) || value1 == null && value2 == null)
continue;
list.Add(new NonEqualProperty(prop.Name, value1, value2));
}
var enumerableTypes =
from prop in properties
from interfaceType in prop.PropertyType.GetInterfaces()
where interfaceType.IsGenericType
let baseInterface = interfaceType.GetGenericTypeDefinition()
where prop.PropertyType != typeof(string) && baseInterface == typeof(IEnumerable<>) || baseInterface == typeof(IEnumerable)
select prop;
foreach (var prop in enumerableTypes)
{
var collection = prop.GetValue(first, null);
}
return list;
}
だから、すべての単純タイプ+文字列の作品の比較。
今、IEnumerableを反復したいと思います(クラスは常に列挙できますが、そうでない場合は大事です)、再帰を使用して値を比較します。このようなもの:
foreach (var prop in enumerableTypes)
{
var typeOfItemsInList= ...;
var collection1 = (IEnumerable<typeOfItemsInList>) prop.GetValue(first, null);
var collection2 = (IEnumerable<typeOfItemsInList>) prop.GetValue(second, null);
for (int i = 0; i < collection1.Count; i++)
{
var item1 = collection1[i];
var item2 = collection2[i];
Compare<typeOfItemsInList>(item1, item2, list);
}
}
どうすれば達成できますか?
ここではリスト内の項目の順序や順序は考慮されていません。後で修正します。これに似た
私はあなたの質問を見て時間を持っていませんが、私は前に、このような比較演算子で働いてきたし、これを追加したい:例えば(Null許容型を忘れてはいけませんint?)、日付と浮動小数点数などは、格納メカニズムと丸め誤差の違いによって比較に失敗する可能性があります。彼らは周りに来て、そうでなければ何かの点であなたを驚かせます:) – john
質問は何ですか? –
NUnitなどのテストライブラリを使用するだけではどうですか?これは、あなたが探している機能などを提供します。 – mireigi