3

以下に示すのは、ジェネリック範囲クラスです。これの目的は、範囲を保存し、後で要求されたときに、指定された値が範囲内にあるかどうか (ブール値) を指定することです。

「条件付きをポリモーフィズムに置き換える」という複数の投稿、質問、ブログなどを読みました

私の質問は、各クラスが文字通り 1 行のコードを持つ複数のクラスにコードを分割する価値があるということです。以下のコードが私の言いたいことを示してくれることを願っています。

このクラスは、ここには示されていませんが、さらに 2 つのクラスに依存していますが、必要な場合は後で含めることができます。

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

Public メソッドは、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

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

I think what you have is fine, as long as it's not going to need to expand much in the future, and you don't need this to be a public class that can be extended in other assemblies. If you'd like a bit more flexibility, you could either use polymorphism, or make a Func<T, bool> (probably private, since you probably just want to expose the Contains method, and not the fact that it's implemented using a Func) that is set when RangeType is set. Then your Contains method becomes return myFunc(value);.

于 2012-04-27T20:47:49.260 に答える
1

さまざまなクラスに分割すると、既存のコードを変更せずに、Contains を拡張できます。この場合、contains のすべての基本をここでカバーしているため、あまり意味がありませんが、他の場合には拡張性が非常に役立ちます。

于 2012-04-27T20:36:52.587 に答える