问题在于单词“null”。它是什么意思?
null
可能意味着值无法确定,抛出了异常,仅仅是该值为空,或者其他一些上下文的含义。你的问题是一个完美的例子,因为你自己是任意地表明,在你看来,
null
表示字符串解析失败。
Microsoft的TryParse范例很好,但只适用于有限的使用场景。考虑以下情况:
- string == "89"
- string == null
- string == "Hello World"
- string == ""
- string == "2147483650"
然而,你唯一的选择是将整数或空值分配给输出,并返回true或false。
假设它起作用了,那么你会用这些信息做什么?像这样:
int? value = null;
if (int.TryParse(Session["Key"].ToString(), out value)) {
if (value == null)
else
}
else {
}
考虑一下这个 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;
if (!int.TryParse(input, out tempOutput))
return false;
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
变量。第三个选择是使用一个描述性的单子,类似于这样:
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)) {
return Maybe.Derived(tempInteger);
}
long tempLong;
if (long.TryParse(input, out tempLong))
return Maybe.OutOfRange();
return Maybe.NotParsable();
}
return Maybe.Success(tempInteger);
}
您可以将单一的可枚举值视为单子,或者像这样使用它们:
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
可能意味着什么。
(int?)(Session["Key"])
- Alexei LevenkovSession["Key"] as int?
,如果失败则返回可空。 - Gregint?
值或缺少的键 - 两者都应该能够成功地进行转换/强制类型转换。我没有看到任何“失败”的情况... - Alexei Levenkov