2012-04-25 10 views
5

をNULLABLEするタイプを変更することはできません一般的なコンバータは、私はここで、一般的なコンバータ</p> <p>を作成しています一般的な方法で

bool TryReaderParse<TType>(object data, out TType value) 
{ 
    value = default(TType); 
    Type returnType = typeof(TType); 
    object tmpValue = null; 

    if (returnType == typeof(DateTime)) 
    { 
     tmpValue = StringToDatetime(data.ToString()); 
    } 
    else if (returnType == typeof(DateTime?)) // THIS IF FIRES 
    { 
     tmpValue = StringToNullableDatetime(data.ToString()); 
    } 

    value = (TType)Convert.ChangeType(tmpValue, returnType); // THROWS 
} 

public DateTime? StringToNullableDatetime(string date) 
{ 
    DateTime? datetime = null; 
    if (!string.IsNullOrEmpty(date)) 
    { 
     datetime = DateTime.Parse(date, new CultureInfo(Resources.CurrentCulture)); 
    } 

    return datetime; 
} 

のサンプルコードであり、これは、私はそれを使用する方法です:

void foo() 
{ 
    DateTime? date = null; 
    TryReaderParse<DateTime?>("25/12/2012", out date); 
} 

スローされた例外は、DateTimeからNullable<DateTime>に変換できないことを示します。このメソッドはnullable型を作成して返しますので、どのようにキャストに失敗しますか?

最後に、この特定の例では、null可能なDateTimeが必要です。

編集問題はStringToNullableDatetime方法はDatetime?を返し、鋳造がConvert.ChangeTypeが合格したことを見ることができない可能性、それをどのように、StringToNullableDatetime方法がNULL可能日時を返すので、それがDatetime

から変換できないと言うことです引数はnull可能ですか?

ps。私は逆の(nullableからのキャスト)を行うthisのような答えを読んだ。 documentationから

答えて

18

スロー例外では、DateTimeからNullable<DateTime>に変換できないことが示されています。このメソッドはnullable型を作成して返しますので、どのようにキャストに失敗しますか?

には、ボックス化されたnullableなどのものは存在しないため、これは失敗します。 DateTime?objectに変換すると、DateTime?がヌルの場合、またはの値がDateTimeの場合は、null参照が返されます。ボックス化されたnullable構造体は決して得られません。そのようなことはない。

したがって、nullまたは有効なDateTimeがそのボックスに表示されます。変換可能なDateTimeに変換するようにConvertに指示すると、Convertはそれを行う方法を知らない。

私のアドバイスは、この攻撃行為を完全に放棄することです。;このコードはジェネリックスを濫用する境界線です。特定のタイプのジェネリックのスイッチを入れるたびに、あなたのコードはgenericでなくなり、おそらく間違っているでしょう。あなたはその後、日時の「試す」スタイルの方法を実行したい場合はちょうどそれを書く:

DateTime? TryReadDateTime(object data) 
{ 
    ... return null if the object cannot be read as a datetime ... 
} 

あなたが読むことを意図し、すべてのタイプのため、このような方法を記述します。ユーザーむしろ記述します。

DateTime d; 
bool b = TryRead<DateTime>(data, out d); 
if (b) ... 
0

場合、この行はエラーになります:

値がnullで、conversionTypeが値型

Nullable<T>は、このようにあなたができない、構造体、したがって値型であるが値がnullの場合は、このメソッド呼び出しを使用します。あなたはすでに別々に日付を扱っています。だから、とにかくこれらの場合にChangeTypeを使用するのはなぜですか?

+0

より

DateTime? d = TryReadDateTime(data); if (d != null) ... 

は私の質問を編集しました。私の問題は、Nullableのdatetimeを返すことができないことです。 'Convert.ChangeType'行は、渡された引数がNULL可能であることを見ることができません – Odys

0

nullables、ジェネリックス、ボクシングのやりとりは奇妙です。あなたは、2つのメソッドを定義したほうが良いことがあります。

第二の方法の中で
 
bool TryReaderParse(object data, out TType value); 
bool TryReaderParse(object data, out TType? value) where TType : struct; 

、あなたのコードは、単にTTypeを生成し、問題なくTType?に割り当てることができます。

+2

まず、メソッドは制約だけで過負荷にならないかもしれません。第2に、メソッドがnull値を返す場合、なぜ* bool *を返す必要があるのでしょうか?これを行うつもりなら、正しいシグネチャは 'T TryParseClass (オブジェクトデータ)です。ここで、T:class'と' T? TryParseStruct (オブジェクトデータ)T:struct'。ブールは必要ありません。 –

関連する問題