我如何用c#优雅地做到这一点?
例如,一个数字可以是1到100之间。
我知道一个简单的if (x >= 1 && x <= 100)就足够了;但是有很多语法糖和新特性不断添加到c# /。Net这个问题是关于更习惯的(一个可以称之为优雅的)写法。
性能不是问题,但请在非O(1)的解决方案中添加性能说明,因为人们可能会复制粘贴建议。
我如何用c#优雅地做到这一点?
例如,一个数字可以是1到100之间。
我知道一个简单的if (x >= 1 && x <= 100)就足够了;但是有很多语法糖和新特性不断添加到c# /。Net这个问题是关于更习惯的(一个可以称之为优雅的)写法。
性能不是问题,但请在非O(1)的解决方案中添加性能说明,因为人们可能会复制粘贴建议。
当前回答
2022年6月
int id = 10;
if(Enumerable.Range(1, 100).Select(x => x == id).Any()) // true
其他回答
if (value > 1 && value < 100)
{
// do work
}
else
{
// handle outside of range logic
}
如果这是偶然的,你只需要一个简单的If。如果这种情况在很多地方都发生,你可能会考虑这两个:
PostSharp。在方法编译后,用“注入”代码的属性来装饰方法。我不确定,但我可以想象它可以用来做这个。
喜欢的东西:
[Between("parameter", 0, 100)]
public void Foo(int parameter)
{
}
代码合同。优点是可以在编译时通过对代码和使用代码的地方进行静态验证来检查约束。
我不知道,但我用这个方法:
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);
}
编辑:提供了新的答案。 当我写这个问题的第一个答案时,我刚刚开始使用c#,事后我意识到我的“解决方案”是幼稚和低效的。
我最初的回答是: 我会选择更简单的版本:
' if(Enumerable.Range(1100).Contains(intInQuestion)){…DoStuff;} '
更好的方法
因为我还没有看到任何其他更有效的解决方案(至少根据我的测试),我将再试一次。
新的和更好的方法,也适用于负范围:
// Returns true if x is in range [min..max], else false
bool inRange(int x, int min=1, int max=100) => ((x - max)*(x - min) <= 0);
这可以用于正负范围,并且默认为
1 . . 100(包括)并使用x作为数字来检查,然后是由min和max定义的可选范围。
为好的措施添加例子
示例1:
// Returns true if x is in range [min..max], else false
bool inRange(int x, int min=1, int max=100) => ((x - max)*(x - min) <= 0);
Console.WriteLine(inRange(25));
Console.WriteLine(inRange(1));
Console.WriteLine(inRange(100));
Console.WriteLine(inRange(25, 30, 150));
Console.WriteLine(inRange(-25, -50, 0));
返回:
True
True
True
False
True
示例2: 使用100000个1到150之间的随机整数的列表
// Returns true if x is in range [min..max], else false
bool inRange(int x, int min=1, int max=100) => ((x - max)*(x - min) <= 0);
// Generate 100000 ints between 1 and 150
var intsToCheck = new List<int>();
var randGen = new Random();
for(int i = 0; i < 100000; ++i){
intsToCheck.Add(randGen.Next(150) + 1);
}
var counter = 0;
foreach(int n in intsToCheck) {
if(inRange(n)) ++counter;
}
Console.WriteLine("{0} ints found in range 1..100", counter);
返回:
66660 ints found in range 1..100
Execution Time: 0.016 second(s)
如果您关心@Daap对已接受答案的注释,并且只能传递一次值,则可以尝试以下方法之一
bool TestRangeDistance (int numberToCheck, int bottom, int distance)
{
return (numberToCheck >= bottom && numberToCheck <= bottom+distance);
}
//var t = TestRangeDistance(10, somelist.Count()-5, 10);
or
bool TestRangeMargin (int numberToCheck, int target, int margin)
{
return (numberToCheck >= target-margin && numberToCheck <= target+margin);
}
//var t = TestRangeMargin(10, somelist.Count(), 5);