この問題の解決には、いくつかの重要な部分があるようです。
- 同様のタイプを比較していることを確認してください。
- タイプのインスタンスを比較できることを確認してください。
ここにあなたが始めるためのいくつかのアイデアがあります。わかりやすくするために、エラーチェックは省略しました。
推定:
Type type1 = dr1.Cells["SomeName"].ValueType;
Type type2 = dr2.Cells["SomeName"].ValueType;
次に、一方の値をもう一方のタイプに強制変換できるかどうかを確認します。
if (type1 != type2)
{
TypeConverter tc1 = TypeDescriptor.GetConverter(type1);
TypeConverter tc2 = TypeDescriptor.GetConverter(type2);
if (tc1.CanConvertFrom(type2))
{
cell2 = tc1.ConvertFrom(cell2);
type2 = type1;
}
else if (tc1.CanConvertTo(type2))
{
cell1 = tc1.ConvertTo(cell1, type2);
type1 = type2;
}
else if (tc2.CanConvertFrom(type1))
{
cell1 = tc2.ConvertFrom(cell1);
type1 = type2;
}
else if (tc2.CanConvertTo(type1))
{
cell2 = tc2.ConvertTo(cell2, type1);
type2 = type1;
}
else // fallback to string comparison
{
cell1 = tc1.ConvertToString(cell1);
type1 = cell1.GetType();
cell2 = tc2.ConvertToString(cell2);
type2 = cell2.GetType();
}
// cell1 and cell2 should be the same type now
}
同様のタイプのインスタンスができたので、それらを比較する方法を見つける必要があります。
C#4を使用している場合、動的キーワードは友達かもしれません。
dynamic c1 = cell1;
try
{
int compareResult = c1.CompareTo(cell2);
}
catch(Exception)
{
// type1 doesn't implement an IComparable-like interface
}
C#4を使用していない場合は、値が以下を実装しているかどうかを確認できますIComparable
。
if (cell1 is IComparable)
{
int compareResult = ((IComparable)cell1).CompareTo(cell2);
}
または、おそらくそれはジェネリックIComparable<T>
を実装します。その場合、いくつかのリフレクショントリックに頼る必要があるかもしれません:
Type genericComparableType = typeof(IComparable<>);
Type typedComparableType = genericComparableType.MakeGenericType(new Type[] { type1 });
if (typedComparableType.IsInstanceOfType(cell1))
{
MethodInfo compareTo = typedComparableType.GetMethod("CompareTo", new Type[] { type1 });
int compareResult = (int)compareTo.Invoke(cell1, new object[] { cell2 });
}
最後に、Comparer<T>.Default
リフレクションを使用して、機能するかどうかを確認できます。
Type genericComparerType = typeof(Comparer<>);
Type typedComparerType = genericComparerType.MakeGenericType(new Type[] { type1 });
PropertyInfo defaultProperty = typedComparerType.GetProperty("Default", BindingFlags.Static | BindingFlags.Public);
object defaultComparer = defaultProperty.GetValue(null, null);
MethodInfo compare = defaultComparer.GetType().GetMethod("Compare", new Type[] { type1, type1 });
int compareResult = (int)compare.Invoke(defaultComparer, new object[] { cell1, cell2 });
これらのいずれも機能しない場合は、文字列比較にフォールバックする必要があります。