我需要运行一个不同的验证方法说:Method1(int datum),Method2(int datum)... Method5(int datum)取决于这个int属于哪个范围。
我管理这些范围的尝试现在看起来像这样(有很多,下面是简化):
List<Tuple<int,int>> ranges = new List<Tuple<int,int>>()
{
new Tuple<int,int>(10000,25000),
new Tuple<int,int>(30000, 80000),
new Tuple<int,int>(85000, 90000)
}
如何更改以上结构,以便将特定方法绑定到每个范围,以便我可以针对范围测试数据并运行与该范围关联的方法?
感谢您的任何意见。
答案 0 :(得分:3)
这只是关于使用委托和字典,其中键是你的范围并重视方法:
public sealed class RangeOperationManager
{
// A map of ranges to operations
private Dictionary<Tuple<int, int>, Func<Tuple<int, int>, int, bool>> RangeToOperationMap { get; }
= new Dictionary<Tuple<int, int>, Func<Tuple<int, int>, int, bool>>();
// Encapsulates how to add new range to operation mappings.
// It's like a façade method.
public void AddOperation(int min, int max, Func<Tuple<int, int>, int, bool> processor)
=> RangeToOperationMap[Tuple.Create(min, max)] = processor;
public bool Operate(int input)
{
// We try to get an operation associated with a range based on the input
var foundPair = RangeToOperationMap
.SingleOrDefault
(
// Let's see if we find a range for the given input!
pair => input >= pair.Key.Item1
&& input <= pair.Key.Item2
);
// If this "if" evaluates true, it would mean that no range could be found
//
// NOTE: We need to check if retrieved pair isn't key-value pair default
// value because it's an structure (value type).
if (!foundPair.Equals(default(KeyValuePair<Tuple<int, int>, Func<Tuple<int, int>, int, bool>>)))
{
// If some could be found, then we proceed to call the associated
// delegate giving the range and input as arguments!
return foundPair.Value(foundPair.Key, input);
}
else
{
throw new InvalidOperationException("Input couldn't match any of configured ranges");
}
}
}
...例如,上面的class
可以按如下方式使用:
class Program
{
// In some class who knows where...
static bool Method1(Tuple<int, int> range, int input)
{
return true;
}
static bool Method2(Tuple<int, int> range, int input)
{
return true;
}
static bool Method3(Tuple<int, int> range, int input)
{
return true;
}
static void Main(string[] args)
{
RangeOperationManager rangeProcessor = new RangeOperationManager();
rangeProcessor.AddOperation(10000, 25000, Method1);
rangeProcessor.AddOperation(30000, 80000, Method2);
rangeProcessor.AddOperation(85000, 90000, Method3);
bool result1 = rangeProcessor.Operate(12300); // true
bool result2 = rangeProcessor.Operate(35000); // true
bool result3 = rangeProcessor.Operate(89000); // true
}
}
在C#7.0中会有syntactic sugar for tuples!我觉得我需要更新我的答案,以便在C#7.0及更高版本中使用语法集成元组的奇迹。
答案 1 :(得分:1)
您可以创建将范围和验证方法的集合作为参数的类,然后循环所有实例,直到找到有效范围并执行验证方法
public class Range
{
public int Min { get; }
public int Max { get; }
public Range(int min, in max)
{
Min = min;
Max = max;
}
}
public class ValidateRanges
{
private readonly List<Range> _ranges;
private readonly Func<int, bool> _validate;
public ValidateRanges(List<Range> ranges, Func<int, bool> validate)
{
_ranges = ranges;
_validate = validate;
}
bool IsInRange(int value)
{
return _ranges.Any(range => value > range.Min && value < range.Max);
}
public bool Validate(int value)
{
return validate(value);
}
}
然后在您的代码中使用
var validateranges = new[]
{
new ValidateRanges(new[] {new Range(0, 100),new Range(1000, 1100)}, ValidationMethod1),
new ValidateRanges(new[] {new Range(101, 200)}, ValidationMethod2),
new ValidateRanges(new[] {new Range(201, 500)}, ValidationMethod3),
};
foreach (var validation in validateranges.Where(val => val.IsInRange(value)))
{
return validation.Validate(value);
}
return false; // default validation