C# キャストと解析する
質問
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 そして として オペレーター。
解析には入力用の文字列が必要で、キャストにはオブジェクトが必要です。そのため、上記の 2 番目の例では、2 つのキャストを実行する必要があります。1 つはオブジェクトから文字列へ、次に文字列から DateTime へです。最初のものはそうではありません。
ただし、キャストの実行時に例外が発生するリスクがある場合は、TryParse を実行して高コストの例外がスローされるのを回避できるように、2 番目の方法を選択することをお勧めします。それ以外の場合は、最も効率的なルートを選択し、2 回 (オブジェクトから文字列、DateTime へ) キャストするのではなく、1 回 (オブジェクトから DateTime へ) キャストするだけです。
さまざまなテクニックの比較があります。 http://blogs.msdn.com/bclteam/archive/2005/02/11/371436.aspx.