プロパティのセッターにこれがある場合:
decimal? temp = value as decimal?;
値= "90"
しかし、キャスト後、tempはnull ...です.
このキャストを行う適切な方法は何ですか?
タイプが同じ場合にのみ、ボックス化解除が機能します!ターゲット値を含まない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;
小数点を解析する必要があります。ただし、文字列が正しくないときに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)
decimal? temp = (decimal?)value;
を使用する場合
文字列を解析したくないが、null
、decimal
、または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参照のボックス化解除に関するコードコントラクトの警告を回避できます。