26

シナリオ

文字列を null 許容の数値型に解析します。解析が失敗した場合、結果は null になります。それ以外の場合、結果は解析された値になります。

質問

これを達成するために、私は常に次の単純だが長く面倒な方法を使用してきました。

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;

コードの最初のビットが、2 番目のビットと同じくらい短く、きちんとしていて、読みやすいバージョンを知っている人はいますか? コードの最初のビットをカプセル化する拡張メソッドをいつでも作成できることはわかっていますが、拡張メソッドなしで必要なことを行う方法があるかどうか疑問に思っています。

4

7 に答える 7

46

1 つの単純な明示的な型キャストにより、コンパイル可能になります。

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

別のオプションはdefault、目的の null 許容型で演算子を使用することです。

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?;

nullキャストが失敗した場合、これは numericValueになり、素晴らしくクリーンです。

于 2012-10-01T22:34:52.567 に答える
2

問題は、temp が 10 進数で、null... が null であることです。これらは同じ型ではないため、2 つの比較は失敗し、エラーが発生します。

次のいずれかを試してください。

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 に答える