如何使用C#和.NET 3.5/4优雅地完成这项工作?
例如,数字可以在1到100之间.
我知道一个简单的就足够了; 但这个问题的关键词是优雅.这是我的玩具项目不是为了生产.
这个问题不是关于速度,而是关于代码美.停止谈论效率等等; 记住你正在向合唱团讲道.
Dus*_*ine 128
有很多选择:
int x = 30;
if (Enumerable.Range(1,100).Contains(x))
//true
if (x >= 1 && x <= 100)
//true
Run Code Online (Sandbox Code Playgroud)
另外,请查看此SO帖子以获取正则表达式选项.
kem*_*002 88
你的意思是?
if(number >= 1 && number <= 100)
Run Code Online (Sandbox Code Playgroud)
要么
bool TestRange (int numberToCheck, int bottom, int top)
{
return (numberToCheck >= bottom && numberToCheck <= top);
}
Run Code Online (Sandbox Code Playgroud)
Ada*_*son 52
只是为了添加噪声,您可以创建一个扩展方法:
public static bool IsWithin(this int value, int minimum, int maximum)
{
return value >= minimum && value <= maximum;
}
Run Code Online (Sandbox Code Playgroud)
哪个会让你做点什么......
int val = 15;
bool foo = val.IsWithin(5,20);
Run Code Online (Sandbox Code Playgroud)
话虽这么说,当检查本身只有一行时,这似乎是一件愚蠢的事情.
Esb*_*sen 45
正如其他人所说,使用简单的if.
你应该考虑订购.
例如
1 <= x && x <= 100
Run Code Online (Sandbox Code Playgroud)
比阅读更容易阅读
x >= 1 && x <= 100
Run Code Online (Sandbox Code Playgroud)
Oli*_*bes 35
您可以使用一些数学将比较次数从两个减少到一个.这个想法是,如果数字位于范围之外,则两个因子中的一个变为负数,如果数字等于其中一个边界则为零:
如果界限是包容性的:
(x - 1) * (100 - x) >= 0
Run Code Online (Sandbox Code Playgroud)
要么
(x - min) * (max - x) >= 0
Run Code Online (Sandbox Code Playgroud)
如果边界是独占的:
(x - 1) * (100 - x) > 0
Run Code Online (Sandbox Code Playgroud)
要么
(x - min) * (max - x) > 0
Run Code Online (Sandbox Code Playgroud)
但是,在生产代码中我只想写1 < x && x < 100,它更容易理解.
Fer*_*cio 18
通过一些扩展方法滥用,我们可以得到以下"优雅"的解决方案:
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!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
Ant*_*n M 17
我建议这个:
public static bool IsWithin<T>(this T value, T minimum, T maximum) where T : IComparable<T> {
if (value.CompareTo(minimum) < 0)
return false;
if (value.CompareTo(maximum) > 0)
return false;
return true;
}
Run Code Online (Sandbox Code Playgroud)
例子:
45.IsWithin(32, 89)
true
87.2.IsWithin(87.1, 87.15)
false
87.2.IsWithin(87.1, 87.25)
true
Run Code Online (Sandbox Code Playgroud)
当然还有变量:
myvalue.IsWithin(min, max)
Run Code Online (Sandbox Code Playgroud)
它易于阅读(接近人类语言)并适用于任何类似的类型(整数,双,自定义类型......).
让代码易于阅读非常重要,因为开发人员不会浪费"脑循环"来理解它.在长时间的编码会话中,浪费的脑循环会使开发人员更早地感到疲
如果这是偶然的,只if需要一个简单的东西.如果在许多地方发生这种情况,您可能需要考虑以下两点:
就像是:
[Between("parameter", 0, 100)]
public void Foo(int parameter)
{
}
Run Code Online (Sandbox Code Playgroud)
if (value > 1 && value < 100)
{
// do work
}
else
{
// handle outside of range logic
}
Run Code Online (Sandbox Code Playgroud)
使用&&表达式连接两个比较只是最优雅的方法.如果您尝试使用花哨的扩展方法等,则会遇到是否包含上限,下限或两者的问题.一旦开始添加其他变量或更改扩展名以指示包含的内容,您的代码就会变得更长,更难以阅读(对于绝大多数程序员而言).此外,像Resharper这样的工具会警告你,如果你的比较没有意义(number > 100 && number < 1),如果你使用一个方法('i.IsBetween(100,1)')他们就不会这样做.
我要做的唯一其他评论是,如果您要检查输入是否有意图抛出异常,您应该考虑使用代码合同:
Contract.Requires(number > 1 && number < 100)
Run Code Online (Sandbox Code Playgroud)
这比if(...) throw new Exception(...)你更优雅,如果有人试图调用你的方法而不确保数字首先在边界内,你甚至可以获得编译时警告.
编辑:提供了新答案。当我写这个问题的第一个答案时,我刚刚开始使用 C#,事后我意识到我的“解决方案”是/是幼稚和低效的。
我的原始答案:我会选择更简单的版本:
由于我还没有看到任何其他更有效的解决方案(至少根据我的测试),我会再试一次。
新的更好的方法也适用于负范围:
// 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);
Run Code Online (Sandbox Code Playgroud)
这可以用于正范围和负范围,默认范围为
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));
Run Code Online (Sandbox Code Playgroud)
返回:
True
True
True
False
True
Run Code Online (Sandbox Code Playgroud)
示例 2:使用 1 到 150 之间的 100000 个随机整数列表
True
True
True
False
True
Run Code Online (Sandbox Code Playgroud)
返回:
// 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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
306514 次 |
| 最近记录: |