10

概要: 2つのジェネリックC#オブジェクトを取得する必要があります。それらが数値の場合は、より小さいまたはより大きい比較を使用してそれらを比較します。

問題:この投稿で説明されているように、クラスにIComparableを実装させる方法がわかりません:ジェネリックのより小さいおよびより大きい操作を実装する必要があります。それが正しい道でさえないのなら、私もそれを知る必要があります。

背景:より複雑なカスタムバリデーターにあるRequiredIf ValidationAttributeを実装しましたが、equals比較に加えて>および<オプションが必要でした。

コード(ページの3分の1下にある、より複雑なカスタムバリデーターから取得):

private bool IsRequired(object actualPropertyValue)
{
  switch (Comparison)
  {
    case Comparison.IsLessThan:
    case Comparison.IsLessThanOrEqualTo:
    case Comparison.IsGreaterThan:
    case Comparison.IsGreaterThanOrEqualTo:
      if (!Value.IsNumber())
      {
        throw new Exception("The selected comparison option is only applicable to numeric values");
      }
      break;
  }

  switch (Comparison)
  {
    case Comparison.IsNotEqualTo:
      return actualPropertyValue == null || !actualPropertyValue.Equals(Value);
    case Comparison.IsEqualTo:
      return actualPropertyValue != null && actualPropertyValue.Equals(Value);
    case Comparison.IsGreaterThan:
      // THIS LINE FAILS BECAUSE actualPropertyValue DOESN'T IMPLEMENT IComparable 
      return actualPropertyValue != null && (actualPropertyValue.CompareTo(Value) > 0); 
    // The rest of the comparison cases go here...
    default:
      throw new Exception("Comparison value is not defined");
  }
}

静的ヘルパー拡張機能:

public static bool IsNumber(this object value)
{
  if (value is sbyte) return true;
  if (value is byte) return true;
  if (value is short) return true;
  if (value is ushort) return true;
  if (value is int) return true;
  if (value is uint) return true;
  if (value is long) return true;
  if (value is ulong) return true;
  if (value is float) return true;
  if (value is double) return true;
  if (value is decimal) return true;
  return false;
}
4

2 に答える 2

18

キャストできるはずactualPropertyValueですIComparable

IComparable comparable = (IComparable) actualPropertyValue;
return comparable != null && comparable.CompareTo(Value) > 0;

ここでは、「ジェネリック」という単語の使用に興味があることに注意してください。実際に一般的にした場合は、次のように書くことができます。

private bool IsRequired<T>(T actualPropertyValue) where T : IComparable

そうすれば、キャストは必要ありません。

于 2012-07-23T15:58:13.860 に答える
4
int MyCompare (object a, object b)
{
   var ac = a as IComparable;
   var bc = b as IComparable;

    if (ac == null || bc == null)
       throw new NotSupportedException();

    return ac.CompareTo(bc);
 }
于 2012-07-23T16:04:01.993 に答える