有人能改进这段代码吗?我需要消除for
循环。
public bool CheckMobileSim(List<Mobile_Range> numberRange, string MobileNumber)
{
bool SimType = new bool();
string NineDigits = MobileNumber.Substring(0, 9).ToString();
long Number = Convert.ToInt64(NineDigits);
if (numberRange != null)
{
if (numberRange.Count > 0)
{
for (int i = 0; i < numberRange.Count; i++)
{
if ((Number >= numberRange[i].RangeStart && Number < numberRange[i].RangeEnd))
{
SimType = true;
break;
}
}
}
}
return SimType;
}
发布于 2012-10-28 15:20:59
重构步骤1,删除不必要的变量和大括号,并提前返回。
public bool CheckMobileSim(List<Mobile_Range> numberRange, string MobileNumber)
{
if(numberRange == null)
return;
string NineDigits = MobileNumber.Substring(0, 9).ToString();
long Number = Convert.ToInt64(NineDigits);
for (int i = 0; i < numberRange.Count; i++)
if ((Number >= numberRange[i].RangeStart && Number < numberRange[i].RangeEnd))
return true;
return false;
}
我意识到这与“单点回报”的智慧不同,但我并不是一个超级粉丝。当你有像这样的小函数时,这就没有什么意义了。
重构步骤2,经过清理,很容易看出这如何适合于一个简单的LINQ查询
public bool CheckMobileSim(IEnumerable<Mobile_Range> numberRange, string mobileNumber)
{
if(numberRange == null || String.IsNullOrWhitespace(mobleNumber))
return false;
var nineDigits = mobileNumber.Substring(0, 9);
var number = Convert.ToInt64(nineDigits);
return numberRange.Any(n => number >= n.RangeStart && number < n.RangeEnd);
}
由于这是一种公共方法,所以我在IEnumerable中添加了一些检查和下拉列表,这是一个更宽松的契约,您在这里真正需要的就是这个。
顺便说一下,.Net命名约定是用于私有变量的pascalCase和用于公共和保护的局部变量CamelCase。很少使用下划线。
发布于 2012-10-29 08:55:29
你可以这样改进它:
(在代码下面,我谈到了我为什么要做更改)
public bool CheckMobileSim(IEnumerable<MobileRange> numberRange, string mobileNumber)
{
// Sanity checks: You can return false instead of throwing exceptions if you'd like to.
if (numberRange == null)
throw new ArgumentNullException("numberRange");
if (mobileNumber == null)
throw new ArgumentNullException("mobileNumber");
// More sanity checks: You need to be sure that mobileNumber has at least nine
// characters that can be converted to a 64 bit integer.
if (mobileNumber.Length < 9)
return false;
long number;
if (!long.TryParse(mobileNumber.Substring(0,9), out number))
return false;
// You can avoid writing the loop yourself and use LINQ instead.
return numberRange.Any(r => number >= r.RangeStart && number < r.RangeEnd);
}
虽然我在上面使用过的Enumerable.Any
扩展方法在本质上将对以下内容执行相同的操作:
foreach (var item in numberRange)
if (number >= item.RangeStart && number < item.RangeEnd)
return true;
return false;
为什么我要改变numberRange
的类型?
IList<T>
。如果您只想枚举它,那么IEnumerable<T>
就足够了。使用此签名,您可以将List<T>
实例或任何其他IEnumerable<T>
实例(例如数组或HashSet<T>
)传递给此方法。为什么我在前两次检查中抛出异常,而在其他人中返回错误?
mobileNumber
作为Int64
传递,完全避免在此方法中进行转换。我为什么要更改你的变量名?
发布于 2012-10-28 08:08:39
public bool CheckMobileSim(List<Mobile_Range> numberRange, string MobileNumber)
{
var digits = new List<long>();
for (int i = 5; i < 10; i++)
digits.Add(Convert.ToInt64(MobileNumber.Substring(0, i).ToString()));
return numberRange != null &&
numberRange.Any(nr => digits.Any(n => n >= nr.RangeStart && n < nr.RangeEnd));
}
这样,您不需要一个循环,但后面有一个循环。
https://codereview.stackexchange.com/questions/18008
复制相似问题