次のうち、C# でより適切なコードはどれですか?またその理由は?
((DateTime)g[0]["MyUntypedDateField"]).ToShortDateString()
また
DateTime.Parse(g[0]["MyUntypedDateField"].ToString()).ToShortDateString()
最終的に、キャストするのと解析するのとではどちらが良いでしょうか?
g[0]["MyUntypedDateField"] が実際に DateTime オブジェクトである場合は、キャストの方が適しています。本当に DateTime でない場合は、Parse を使用するしかありません (キャストを使用しようとすると、InvalidCastException が発生します)。
キャストは唯一の良い答えです。
ToString と Parse の結果は常に正確であるとは限らないことを覚えておく必要があります。これらの 2 つの関数間を安全に往復できない場合があります。
ToString のドキュメントによると、現在のスレッド カルチャ設定が使用されます。Parse のドキュメントには、現在のスレッド カルチャ設定も使用されていると記載されています (これまでのところ、同じカルチャを使用しています)。
書式設定は、現在の DateTimeFormatInfo オブジェクトのプロパティの影響を受けます。既定では、コントロール パネルの [地域と言語のオプション] 項目から派生します。Parse メソッドが予期せず FormatException をスローする理由の 1 つは、現在の DateTimeFormatInfo.DateSeparator プロパティと DateTimeFormatInfo.TimeSeparator プロパティが同じ値に設定されている場合です。
したがって、ユーザーの設定によっては、ToString/Parse コードが予期せず失敗する可能性があります...
あなたのコードは、変数が日付または日付のように見える文字列のいずれかである可能性があることを示唆しています。日付はキャストで簡単に返すことができますが、文字列は解析する必要があります。解析には 2 つの注意事項があります。
この文字列を解析できるかどうかわからない場合は、 を使用してDateTime.TryParse()
ください。
解析するカルチャへの参照を常に含めます。ToShortDateString()
さまざまな場所でさまざまな出力を返します。ほとんどの場合、同じカルチャを使用して解析する必要があります。この関数は両方の状況に対処することをお勧めします。
private DateTime ParseDateTime(object data)
{
if (data is DateTime)
{
// already a date-time.
return (DateTime)data;
}
else if (data is string)
{
// it's a local-format string.
string dateString = (string)data;
DateTime parseResult;
if (DateTime.TryParse(dateString, CultureInfo.CurrentCulture,
DateTimeStyles.AssumeLocal, out parseResult))
{
return parseResult;
}
else
{
throw new ArgumentOutOfRangeException("data",
"could not parse this datetime:" + data);
}
}
else
{
// it's neither a DateTime or a string; that's a problem.
throw new ArgumentOutOfRangeException("data",
"could not understand data of this type");
}
}
次に、このように呼び出します。
ParseDateTime(g[0]["MyUntypedDateField").ToShortDateString();
不正なデータは例外をスローするので、それをキャッチする必要があることに注意してください。
また; 'as' 演算子は DateTime データ型では機能しません。これは参照型でのみ機能し、DateTime は値型であるためです。
@Brian R. Bondy が指摘したように、 g[0]["MyUntypedDateField"]の実装に依存します。安全な方法は、DateTime.TryParseとas演算子を使用することです。
解析には入力用の文字列が必要で、キャストにはオブジェクトが必要です。そのため、上記の 2 番目の例では、オブジェクトから文字列へのキャストと、文字列から DateTime へのキャストの 2 つのキャストを実行する必要があります。最初はしません。
ただし、キャストを実行するときに例外が発生するリスクがある場合は、TryParse を実行して高価な例外がスローされるのを回避できるように、2 番目の方法を使用することをお勧めします。それ以外の場合は、最も効率的なルートに進み、2 回 (オブジェクトから文字列、DateTime へ) キャストするのではなく、1 回 (オブジェクトから DateTime へ) キャストするだけです。
http://blogs.msdn.com/bclteam/archive/2005/02/11/371436.aspxには、さまざまな手法の比較があります。