3

下面显示的是一个通用范围类。这样做的目的是保存一个范围,然后在请求时指定(布尔值)给定值是否在范围内。

我已经阅读了多个帖子、问题、博客等,上面写着“用多态性替换条件

我的问题是,是否真的值得将代码分成多个类,每个类实际上只有一行代码。希望下面的代码能说明我的意思。

该类依赖于另外两个类,此处未显示,但如果有人需要它,我可以稍后包含它。

namespace Common.Utilities
{
    public class GenericRange<T>
       where T : struct, IComparable<T>
   {
      #region Properties
      public T Min { get; private set; }
      public T Max { get; private set; }
      public GenericRangeType RangeType { get; private set; }
      #endregion

      #region Constructors
      public GenericRange(T min, T max, GenericRangeType rangeType = GenericRangeType.Inclusive)
      {
         // Check Parameters
         Min = min;
         Max = max;
         RangeType = rangeType;
      }
      #endregion

      #region Methods
      #region Private
      private bool IsInclusive(T value)
      {
         return value.IsGreaterThanOrEqualTo(Min) && value.IsLessThanOrEqualTo(Max);
      }

      private bool IsInclusiveMin(T value)
      {
         return value.IsGreaterThanOrEqualTo(Min) && value.IsLessThan(Max);
      }

      private bool IsInclusiveMax(T value)
      {
         return value.IsGreaterThan(Min) && value.IsLessThanOrEqualTo(Max);
      }

      private bool IsExclusive(T value)
      {
         return value.IsGreaterThan(Min) && value.IsLessThan(Max);
      }
      #endregion

      #region Public
      public bool Contains(T value)
      {
         switch (RangeType)
         {
            case GenericRangeType.Inclusive: return IsInclusive(value);
            case GenericRangeType.InclusiveMin: return IsInclusiveMin(value);
            case GenericRangeType.InclusiveMax: return IsInclusiveMax(value);
            case GenericRangeType.Exclusive: return IsExclusive(value);
            default: throw new NotImplementedException();
         }
      }

      public override string ToString()
      {
         return String.Format("Min: {0}, Max: {1}, Type: {2}", Min, Max, RangeType);
      }
      #endregion
      #endregion
    }
}

唯一的公共方法是:Contain 和 ToString。如果我通过多态正确理解它,我应该为每个比较类型创建一个单独的具体类,然后使 Contain 成为一个虚拟方法。

我想了解的主要事情是,好处/优势是什么?

如果这是这个问题的错误地方,那么我很抱歉。让我知道,我会移动它。

编辑 1: 如果有人需要,可以完成此操作的附加代码:

public static class ComparableExtensions
{
    public static bool IsEqualTo<T>(this T leftHand, T value) where T : IComparable<T>
    {
        return leftHand.CompareTo(value) == 0;
   }

    public static bool IsGreaterThan<T>(this T leftHand, T value) where T : IComparable<T>
    {
        return leftHand.CompareTo(value) > 0;
    }
    public static bool IsGreaterThanOrEqualTo<T>(this T leftHand, T value) where T : IComparable<T>
    {
        return leftHand.CompareTo(value) >= 0;
    }

    public static bool IsLessThan<T>(this T leftHand, T value) where T : IComparable<T>
    {
        return leftHand.CompareTo(value) < 0;
    }
    public static bool IsLessThanOrEqualTo<T>(this T leftHand, T value) where T : IComparable<T>
    {
        return leftHand.CompareTo(value) <= 0;
    }
}   

public enum GenericRangeType
{
    Inclusive,
    Exclusive,
    InclusiveMin,
    InclusiveMax
}
4

3 回答 3

1

将其分解为不同的类可以让您在不更改现有代码的情况下扩展 Contains。在这种情况下,它没有太大意义,因为您已经在这里涵盖了 contains 的所有基础,但在其他情况下,可扩展性可能非常有用。

于 2012-04-27T20:36:52.587 回答
1

IMO - 您使用的泛型更像是“模板”类,而不是经典 OOPS 术语中的纯粹基类。

我的意思是,如果你写过这样的类:

public class GenericRange{...}

public class IntRange : GenericRange{...}
public class DecimalRange : GenericRange{...}

在这种情况下,将 Contains 的实现真正分解为单独的子类型作为重写方法是有意义的。

但是由于您使用的是代码模板,因此您确实获得了多态行为的好处,这取决于您初始化模板类的方式。

所以,如果你这样做了:

new GenericRange<int>(1, 100, inclusive);
new GenericRange<decimal>(1.0, 100.0, inclusive);

您确实已经完成了多态行为,我认为这是泛型的一大好处,因为它允许您对此类代码进行模板化,而不是像前面所示的那样拥有专门的子类。

于 2012-04-27T20:43:34.127 回答
1

我认为你所拥有的很好,只要它将来不需要扩展太多,并且你不需要它成为可以在其他程序集中扩展的公共类。如果您想要更多的灵活性,您可以使用多态性,或者制作一个Func<T, bool>(probably private,因为您可能只想公开该Contains方法,而不是它是使用 a 实现的事实Func) 设置时RangeType设置。然后你的Contains方法变成return myFunc(value);.

于 2012-04-27T20:47:49.260 回答