我如何用c#优雅地做到这一点?
例如,一个数字可以是1到100之间。
我知道一个简单的if (x >= 1 && x <= 100)就足够了;但是有很多语法糖和新特性不断添加到c# /。Net这个问题是关于更习惯的(一个可以称之为优雅的)写法。
性能不是问题,但请在非O(1)的解决方案中添加性能说明,因为人们可能会复制粘贴建议。
我如何用c#优雅地做到这一点?
例如,一个数字可以是1到100之间。
我知道一个简单的if (x >= 1 && x <= 100)就足够了;但是有很多语法糖和新特性不断添加到c# /。Net这个问题是关于更习惯的(一个可以称之为优雅的)写法。
性能不是问题,但请在非O(1)的解决方案中添加性能说明,因为人们可能会复制粘贴建议。
当前回答
In C, if time efficiency is crucial and integer overflows will wrap, one could do if ((unsigned)(value-min) <= (max-min)) .... If 'max' and 'min' are independent variables, the extra subtraction for (max-min) will waste time, but if that expression can be precomputed at compile time, or if it can be computed once at run-time to test many numbers against the same range, the above expression may be computed efficiently even in the case where the value is within range (if a large fraction of values will be below the valid range, it may be faster to use if ((value >= min) && (value <= max)) ... because it will exit early if value is less than min).
不过,在使用这样的实现之前,请先对目标机器进行基准测试。在某些处理器上,由两部分组成的表达式可能在所有情况下都更快,因为两个比较可能是独立完成的,而在减法和比较方法中,减法必须在比较执行之前完成。
其他回答
通过一些扩展方法的滥用,我们可以得到以下“优雅”的解决方案:
using System;
namespace Elegant {
public class Range {
public int Lower { get; set; }
public int Upper { get; set; }
}
public static class Ext {
public static Range To(this int lower, int upper) {
return new Range { Lower = lower, Upper = upper };
}
public static bool In(this int n, Range r) {
return n >= r.Lower && n <= r.Upper;
}
}
class Program {
static void Main() {
int x = 55;
if (x.In(1.To(100)))
Console.WriteLine("it's in range! elegantly!");
}
}
}
if (value > 1 && value < 100)
{
// do work
}
else
{
// handle outside of range logic
}
static class ExtensionMethods
{
internal static bool IsBetween(this double number,double bound1, double bound2)
{
return Math.Min(bound1, bound2) <= number && number <= Math.Max(bound2, bound1);
}
internal static bool IsBetween(this int number, double bound1, double bound2)
{
return Math.Min(bound1, bound2) <= number && number <= Math.Max(bound2, bound1);
}
}
使用
double numberToBeChecked = 7;
var result = numberToBeChecked.IsBetween(100,122);
var result = 5.IsBetween(100,120);
var result = 8.0.IsBetween(1.2,9.6);
优雅是因为它不需要确定两个边界值中哪个先大。它也不包含分支。
public static bool InRange(float val, float a, float b)
{
// Determine if val lies between a and b without first asking which is larger (a or b)
return ( a <= val & val < b ) | ( b <= val & val < a );
}
像这样的怎么样?
if (theNumber.isBetween(low, high, IntEx.Bounds.INCLUSIVE_INCLUSIVE))
{
}
扩展方法如下(已测试):
public static class IntEx
{
public enum Bounds
{
INCLUSIVE_INCLUSIVE,
INCLUSIVE_EXCLUSIVE,
EXCLUSIVE_INCLUSIVE,
EXCLUSIVE_EXCLUSIVE
}
public static bool isBetween(this int theNumber, int low, int high, Bounds boundDef)
{
bool result;
switch (boundDef)
{
case Bounds.INCLUSIVE_INCLUSIVE:
result = ((low <= theNumber) && (theNumber <= high));
break;
case Bounds.INCLUSIVE_EXCLUSIVE:
result = ((low <= theNumber) && (theNumber < high));
break;
case Bounds.EXCLUSIVE_INCLUSIVE:
result = ((low < theNumber) && (theNumber <= high));
break;
case Bounds.EXCLUSIVE_EXCLUSIVE:
result = ((low < theNumber) && (theNumber < high));
break;
default:
throw new System.ArgumentException("Invalid boundary definition argument");
}
return result;
}
}