需要使用大于或小于比较两个通用对象

10

简介:我需要比较两个通用的C#对象,如果它们是数字,则使用小于或大于比较进行比较。

问题:我无法弄清楚如何让我的类实现IComparable,就像在这篇文章中描述的那样:Having to implement a generic less than and greater than operation。 如果这甚至不是正确的方法,那么我也需要知道。

背景:我已经实现了在ASP.NET MVC 3中更复杂的自定义验证器中找到的RequiredIf ValidationAttribute,但需要在等于比较之外添加>和<选项。

代码(取自ASP.NET MVC 3中更复杂的自定义验证器,在页面的三分之一处):

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;
}
2个回答

18

听起来你只需要将 actualPropertyValue 强制转换为 IComparable 类型:

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

请注意,您在这里使用“通用”一词很奇怪。如果您实际上使其通用,可以编写以下代码:
private bool IsRequired<T>(T actualPropertyValue) where T : IComparable

那么你就不需要用到强制类型转换了。

谢谢Jon。我尝试了你的第二个选项,似乎可以编译,所以我会继续测试它。然而,当我实现它时,ReSharper警告我actualPropertyValue == null语句可能会与null值类型进行比较。这个警告可以忽略吗?其次,根据我参考的链接,我处理的不是“通用”对象吗?或者我使用了错误的术语? - bigmac

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);
 }

谢谢 Richard,但是返回行不应该是 return ac.CompareTo(bc); 吗? - bigmac
Richard,我实际上使用了Jon的方法,但是我会将你的作为一个很好的扩展方法用于快速比较。谢谢你的帮助! - bigmac

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接