2012-02-24 5 views
15

は、私は以下のコードを持っていると私はまた、文字列から指定された型に文字列を変換する必要があるだろう:実行時に決定されるNullable型に文字列を変換する方法は?

Invalid cast from 'System.String' to 'System.Nullable`1[[System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'. 

どうだろう:

Type t = Type.GetType("System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"); 

      object d = Convert.ChangeType("2012-02-23 10:00:00", t); 

は、私は以下のエラーメッセージが表示されますきれいに可能ですか?

Type possiblyNullableType = Type.GetType("System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"); 

    var underlyingType = Nullable.GetUnderlyingType(possiblyNullableType); 

    Object result; 

    // if it's null, it means it wasn't nullable 
    if (underlyingType != null) 
    { 
     result = Convert.ChangeType("2012-02-23 10:00:00", underlyingType); 
    } 

は、任意のより良い方法があるでしょう:

は、私は1つの醜い方法があれば使用してタイプがNULL可能であるかどうかをチェックすることです知っていますか?

ありがとう、

答えて

29

二つの問題があります。 。

まず、Convert.ChangeTypeプレーンはNULL値の型をサポートしていません。

第2に、結果がボックス化されて(objectに割り当てられている)、すでにDateTimeに変換されています。

あなたでし特殊なケースNULL可能なタイプ:

string s = "2012-02-23 10:00:00"; 
Type t = Type.GetType("System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"); 
object d; 

if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) 
{ 
    if (String.IsNullOrEmpty(s)) 
     d = null; 
    else 
     d = Convert.ChangeType(s, t.GetGenericArguments()[0]); 
} 
else 
{ 
    d = Convert.ChangeType(s, t); 
} 
+0

なぜt.IsGenericTypeをチェックする必要がありますか? t.GetGenericTypeDefinition()== typeof(Nullable <>)部分はそれをカバーします。それじゃない? –

+2

@William 'GetGenericTypeDefinition()'は、型がジェネリックでない場合に例外をスローします。 – hvd

1

このようなことはありますか?あなたが本当にそれを動的に行う必要がない限り。

if (string.IsNullOrEmpty(input)) 
{ 
    return new DateTime?(); 
} 
else 
{ 
    return new DateTime?(DateTime.Parse(input)); 
} 

おそらくあなたは、あなたのタイプは「NULL可能」のいずれかのタイプであるかどうかを確認するために、その後、多分あなたはここで役に立つ何かを見つけることができるチェックすることができ:

Convert string to nullable type (int, double, etc...)

+0

私ができます」 DateTimeを指定すると、実行時に決定されます。 –

+0

'return new DateTime?();'は 'return null;'に置き換えてください。 – ken2k

+0

あなたが現在やっていることとは対照的に、あなたがしようとしていることについて何らかの情報を提供できるのであれば、私たちは助言することができますか? – Paddy

9

私はほとんどのシナリオ(一般的なタイプでテストされていない)で動作する汎用的なヘルパーメソッドの下に書いている:

static void Main(string[] args) 
{ 
    Object result = 
     ConvertValue(
      "System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", 
      "2012-02-23 10:00:00"); 
} 

public static Object ConvertValue(string typeInString, string value) 
{ 
    Type originalType = Type.GetType(typeInString); 

    var underlyingType = Nullable.GetUnderlyingType(originalType); 

    // if underlyingType has null value, it means the original type wasn't nullable 
    object instance = Convert.ChangeType(value, underlyingType ?? originalType); 

    return instance; 
} 
+0

ありがとうございます。これは最もエレガントで実用的なソリューションです。 –

2
public static T GetValue<T>(string Literal, T DefaultValue) 
    { 
     if (Literal == null || Literal == "" || Literal == string.Empty) return DefaultValue; 
     IConvertible obj = Literal; 
     Type t = typeof(T); 
     Type u = Nullable.GetUnderlyingType(t); 

     if (u != null) 
     { 
      return (obj == null) ? DefaultValue : (T)Convert.ChangeType(obj, u); 
     } 
     else 
     { 
      return (T)Convert.ChangeType(obj, t); 
     } 
    } 
関連する問題