我如何用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 production code I would simply write 1 <= x && x <= 100 This is easy to understand and very readable. Starting with C#9.0 we can write x is >= 1 and <= 100 Note that we must write x only once. is introduces a pattern matching expression where and is part of the pattern. && would require us to repeat x is as in x is >= 1 && x is <= 100 Here is a clever method that reduces the number of comparisons from two to one by using some math. There is not necessarily a performance advantage in doing so, but it is elegant. The idea is that one of the two factors becomes negative if the number lies outside of the range and zero if the number is equal to one of the bounds: If the bounds are inclusive: (x - 1) * (100 - x) >= 0 or (x - min) * (max - x) >= 0 If the bounds are exclusive: (x - 1) * (100 - x) > 0 or (x - min) * (max - x) > 0
其他回答
只是为了增加这里的噪音,你可以创建一个扩展方法:
public static bool IsWithin(this int value, int minimum, int maximum)
{
return value >= minimum && value <= maximum;
}
这样你就能做…
int val = 15;
bool foo = val.IsWithin(5,20);
话虽如此,当检查本身只有一行时,这样做似乎是一件愚蠢的事情。
在c#中,关于速度和代码原的最佳解决方案,只有一次比较,没有约束检查,并且不会因溢出而容易出错:
public static bool IsInRange(int value, int min, int max) => (uint)(value - min) <= (uint)(max - min);
最小值和最大值包括在内。
这些是一些可以提供帮助的扩展方法
public static bool IsInRange<T>(this T value, T min, T max)
where T : System.IComparable<T>
{
return value.IsGreaterThenOrEqualTo(min) && value.IsLessThenOrEqualTo(max);
}
public static bool IsLessThenOrEqualTo<T>(this T value, T other)
where T : System.IComparable<T>
{
var result = value.CompareTo(other);
return result == -1 || result == 0;
}
public static bool IsGreaterThenOrEqualTo<T>(this T value, T other)
where T : System.IComparable<T>
{
var result = value.CompareTo(other);
return result == 1 || result == 0;
}
我不知道,但我用这个方法:
public static Boolean isInRange(this Decimal dec, Decimal min, Decimal max, bool includesMin = true, bool includesMax = true ) {
return (includesMin ? (dec >= min) : (dec > min)) && (includesMax ? (dec <= max) : (dec < max));
}
这是我使用它的方式:
[TestMethod]
public void IsIntoTheRange()
{
decimal dec = 54;
Boolean result = false;
result = dec.isInRange(50, 60); //result = True
Assert.IsTrue(result);
result = dec.isInRange(55, 60); //result = False
Assert.IsFalse(result);
result = dec.isInRange(54, 60); //result = True
Assert.IsTrue(result);
result = dec.isInRange(54, 60, false); //result = False
Assert.IsFalse(result);
result = dec.isInRange(32, 54, false, false);//result = False
Assert.IsFalse(result);
result = dec.isInRange(32, 54, false);//result = True
Assert.IsTrue(result);
}
关于优雅,最接近数学符号(a <= x <= b)的方法略微提高了可读性:
public static bool IsBetween(this int value, int min, int max)
{
return min <= value && value <= max;
}
为了进一步说明:
public static bool IsOutside(this int value, int min, int max)
{
return value < min || max < value;
}