web-dev-qa-db-ja.com

オブジェクトを10進数にキャストしますか? (ヌル可能な10進数)

プロパティのセッターにこれがある場合:

decimal? temp = value as decimal?;

値= "90"

しかし、キャスト後、tempはnull ...です.

このキャストを行う適切な方法は何ですか?

31
Natrium

タイプが同じ場合にのみ、ボックス化解除が機能します!ターゲット値を含まないobjectをボックス化解除することはできません。必要なのは、

decimal tmpvalue;
decimal? result = decimal.TryParse((string)value, out tmpvalue) ?
                  tmpvalue : (decimal?)null;

これは、値がdecimalとして解析可能かどうかを調べます。はいの場合、result;に割り当てます。それ以外の場合は、nullを割り当てます。次のコードはほぼ同じであり、条件演算子?:

decimal tmpvalue;
decimal? result = null;
if (decimal.TryParse((string)value, out tmpvalue))
    result = tmpvalue;
67
Konrad Rudolph

小数点を解析する必要があります。ただし、文字列が正しくないときに10進数をnullにするには、TryParseを使用します。

decimal parsedValue;
decimal? temp = decimal.TryParse(value, out parsedValue)
                ? value
                : (decimal?)null;

これにより、不適切な形式の文字列の解析中に例外を回避できます。

ほとんどすべてのプリミティブ型は、文字列から変換するためのParseおよびTryParseメソッドを提供します。

また、プロバイダの引数のカルチャをメソッドに渡して、小数点区切り文字の問題を回避することもお勧めします。別のシステムから読み込んでいる場合は、CultureInfo.InvariantCultureを使用することをお勧めします(ただし、デフォルトではありません)。

bool TryParse(string s, NumberStyles style,
  IFormatProvider provider, out decimal result)
5

decimal? temp = (decimal?)value;を使用する場合

2
StevenMcD

文字列を解析したくないが、nulldecimal、またはnull入力可能なdecimalのいずれかを受け取るようにしたい場合は、次のようにすることができます。

public static Nullable<T> Convert<T>(object input) 
    where T : struct
{
    if (input == null)
        return null;
    if (input is Nullable<T> || input is T)
        return (Nullable<T>)input;
    throw new InvalidCastException();
}

例外を回避したい場合は、代わりに最後の行にnullを返すようにできますが、実際のnull値と不正なキャストを区別することはできません。

「as」演算子は値の型では機能しないため、「is」演算子を使用する必要があり、チェックせずにキャストするとInvalidCastExceptionがスローされる場合があることに注意してください。

拡張メソッドにすることもできます。

public static class ObjectExtensions
{
    public static Nullable<T> ToNullable<T>(this object input)
        where T : struct
    {
        if (input == null)
            return null;
        if (input is Nullable<T> || input is T)
            return (Nullable<T>)input;
        throw new InvalidCastException();
    }
}

そして、次のように使用します:

object value = 123.45m;
decimal? dec = value.ToNullable<decimal>();

これにより、null参照のボックス化解除に関するコードコントラクトの警告を回避できます。

2
Stephen Drew