下面显示的是Generic Range类。这样做的目的是保存一个Range,然后在请求时指定(boolean),如果给定的值在范围内。
我已阅读多篇帖子,问题,博客等说“" Replace Conditional with Polymorphism"
我的问题是,真的值得将代码分成多个类,其中每个类实际上都有一行代码。希望下面的代码能说明我的意思。
该类依赖于另外两个类,这里没有显示,但是如果有人需要它,我可以在以后包含它。
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。 如果我通过多态性正确理解它,我应该为每个comparisson类型创建一个单独的具体类,然后make 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
}
答案 0 :(得分:1)
将其分解为不同的类可让您在不更改现有代码的情况下扩展Contains。在这种情况下,它没有太多意义,因为你已经覆盖了包含的所有基础,但在其他情况下,可扩展性非常有用。
答案 1 :(得分: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);
你已经完成了多态行为,我认为这是Generics的一大好处,因为它允许你模拟这样的代码而不是像前面所示的那样有专门的子类。
答案 2 :(得分:1)
我认为你所拥有的是好的,只要它将来不需要扩展太多,你不需要这个可以在其他程序集中扩展的公共类。如果你想要更多的灵活性,你可以使用多态,或者制作一个Func<T, bool>
(可能是private
,因为你可能只想公开Contains
方法,而不是事实上,它是使用Func
实现的,RangeType
设置Contains
时设置。然后,您的return myFunc(value);
方法变为{{1}}。