Whoa, what the TryParse
本文关键字:TryParse the what Whoa | 更新日期: 2023-09-27 18:30:00
我有一个会话,它包含特定的整数值,这些整数值用给定的控件进行索引。通常情况下,以下操作会很好:
int value;
int.TryParse(Session["Key"].ToString(), out value);
但是,我确实需要说明为null。其中,如果string
失败,则默认的out将返回null
。只是我注意到int.TryParse
不适用于:
int? value = null;
int.TryParse(Session["Key"].ToString(), out value);
那么,如何尝试解析,如果失败,将导致null?
我发现了这个问题,微软开发者网络规定:
当此方法返回时,包含带符号的整数值等于s中包含的数字,如果转换成功,或者如果转换失败则为零。如果字符串参数为null或String.Empty,格式不正确,或表示小于"最小值"或大于"最大值"的数字。这参数传递时未初始化。
它清楚地表明,如果int.TryParse
失败,则整数将保持零值在我使用的例子中,零可能是一个有效值。所以我需要null
,有什么想法吗?
当然;利用int.TryParse
的返回值(如果转换成功与否,则返回):
int? retValue = null;
int parsedValue = 0;
if (int.TryParse(Session["Key"].ToString(), out parsedValue))
retValue = parsedValue;
else
retValue = null;
return retValue;
我承认有点冗长,但你可以把它包装成一个函数。
int tmp;
int? value = int.TryParse(Session["Key"].ToString(), out tmp) ? (int?)tmp : null;
问题是单词"null"。它是什么意思?null
可能意味着该值不可确定、引发异常、简单地说该值为null或其他上下文意义。你的问题就是一个完美的例子,因为你自己武断地说,在你看来,null
意味着字符串解析失败。
微软的TryParse范例非常棒,但使用范围有限。考虑以下场景:
- string="89"
- 字符串==空
- string=="你好,世界"
- string=="
- string="2147483650"
然而,您唯一的选择是为输出指定Integer或Null,并返回true或false。
假设它有效,你将如何处理这些信息?像这样的东西?
int? value = null;
if (int.TryParse(Session["Key"].ToString(), out value)) {
if (value == null)
// Handle "Appropriate" null
else
// Handle appropriate numeric value
}
else {
// Note: value == null here, and TryParse failed
// Handle null...
// What if the reason it failed was because the number was too big?
// What if the string was Empty and you wanted to do something special?
// What if the string was actually junk? Like "(423)322-9876" ?
// Long-Story Short: You don't know what to do here without more info.
}
考虑这个NullableInt TryParse示例:
public bool TryParseNullableInt(string input, out int? output)
{
int tempOutput;
output = null;
if (input == null) return true;
if (input == string.Empty) return true; // Would you rather this be 0?
if (!int.TryParse(input, out tempOutput))
return false; // What if string was "2147483650"... or "Twenty Three"?
output = tempOutput;
return true;
}
一种解决方案是使用枚举TryParse而不是布尔TryParse:
public ParseStatus TryParseNullableInt(string input, out int? output)
{
int tempInteger;
output = null;
if (input == null) return ParseStatus.Success;
if (input == string.Empty) { output = 0; return ParseStatus.Derived; }
if (!int.TryParse(input, out tempInteger)) {
if (ParseWords(input, out tempInteger)) { // "Twenty Three" = 23
output = tempInteger;
return ParseStatus.Derived;
}
long tempLong;
if (long.TryParse(input, out tempLong))
return ParseStatus.OutOfRange;
return ParseStatus.NotParsable;
}
output = tempInteger;
return ParseStatus.Success;
}
另一个问题是out
变量的存在。第三种选择是使用描述性monad,类似于以下内容:
public Maybe<int?> TryParseNullableInt(string input)
{
if (input == null) return Maybe.Success(null);
if (input == string.Empty) { return Maybe.Derived(0); }
int tempInteger;
if (!int.TryParse(input, out tempInteger)) {
if (ParseWords(input, out tempInteger)) { // "Twenty Three" = 23
return Maybe.Derived(tempInteger);
}
long tempLong;
if (long.TryParse(input, out tempLong))
return Maybe.OutOfRange();
return Maybe.NotParsable();
}
return Maybe.Success(tempInteger);
}
您可以将Monads用作单个可枚举值,或者类似地使用:
Maybe<int?> result = TryParseNullableInt("Hello");
if (result.HasValue) {
if (result.Status == ParseStatus.Success)
// Do something you want...
else if (result.Status == ParseStatus.Derived)
// Do something else... more carefully maybe?
}
else if (result.Status == ParseStatus.OutOfRange)
MessageUser("That number is too big or too small");
else if (result.Status == ParseStatus.NotParsable)
// Do something
有了Monads,以及可能的枚举TryParses,您现在可以从描述性返回中获得所需的所有信息,并且没有人需要猜测null
可能意味着什么。