26

设想

将字符串解析为可为空的数值类型。如果解析不成功,结果应该为空;否则结果应该是解析后的值。

问题

为了做到这一点,我一直使用以下简单但冗长烦人的方法:

string numericString = "...";

decimal? numericValue;
decimal temp;
if (decimal.TryParse(numericString, out temp))
{
    numericValue = temp;
}
else
{
    numericValue = null;
}

我使用上述方法是因为以下内容无法编译

decimal temp;
decimal? numericValue = decimal.TryParse(numericString, out temp) ? temp : null;

有人知道第一个代码的版本和第二个代码一样短、整洁和可读吗?我知道我总是可以编写一个封装第一部分代码的扩展方法,但我想知道是否有任何方法可以在没有扩展方法的情况下做我想做的事情。

4

7 回答 7

46

一种简单的显式类型转换使其可编译:

decimal temp;
// typecast either 'temp' or 'null'
decimal? numericValue =
  decimal.TryParse(numericString, out temp) ? temp : (decimal?)null;

另一种选择是default在所需的可空类型上使用运算符:

decimal temp;
// replace null with default
decimal? numericValue =
  decimal.TryParse(numericString, out temp) ? temp : default(decimal?);
于 2012-10-01T22:32:50.177 回答
13

我会做这样的事情:

public delegate bool TryParseDelegate<T>(string str, out T value);

public static T? TryParseOrNull<T>(TryParseDelegate<T> parse, string str) where T : struct
{
    T value;
    return parse(str, out value) ? value : (T?)null;
}

decimal? numericValue = TryParseOrNull<decimal>(decimal.TryParse, numericString);

或者您可以将其设为扩展方法:

public static T? TryParseAs<T>(this string str, TryParseDelegate<T> parse) where T : struct
{
    T value;
    return parse(str, out value) ? value : (T?)null;
}

decimal? numericValue = numericString.TryParseAs<decimal>(decimal.TryParse);
于 2012-10-01T22:33:04.210 回答
6

只需将其分解为扩展方法:

public static decimal? ParseDecimal(this string s)
{
    decimal d;
    if (decimal.TryParse(s, out d))
        return d;
    return null;
}

然后你可以像这样使用它:

numericValue = numericString.TryParseDecimal();
于 2012-10-01T22:34:10.600 回答
5

怎么样:

decimal? numericValue = 
    decimal.TryParse(numericString, out temp) ? temp : null as decimal?;

如果强制转换失败,这会生成 numericValue null,并且非常干净。

于 2012-10-01T22:34:52.567 回答
2

问题是 temp 是小数,而 null...为 null。因为它们不是同一类型,所以两者之间的比较失败并出现错误。

尝试:

decimal? numericValue = decimal.TryParse(numericString, out temp) ? (decimal?)temp : null;

或者

decimal? numericValue = decimal.TryParse(numericString, out temp) ? (decimal?)temp : (decimal?)null;
于 2012-10-01T22:40:12.190 回答
1

我认为您应该将其包装在一种方法中以提高可读性:

private decimal? ParseOrDefault(string decimalAsString, decimal? defaultIfInvalidString=null)
{
    decimal result;
    if (decimal.TryParse(decimalAsString, out result))
        return result;
    return defaultIfInvalidString;
}

[Test]
public void ParseOrDefaultTest()
{
    decimal? actual = ParseOrDefault("12", null);
    Assert.AreEqual(12m,actual);

    actual = ParseOrDefault("Invalid string", null);
    Assert.AreEqual(null, actual);
}
于 2012-10-01T23:03:58.367 回答
0

十进制?weight = decimal.TryParse(weightEditText.Text, out var tempWeight) ?tempWeight:默认(十进制?)

于 2020-04-20T12:12:13.200 回答