web-dev-qa-db-ja.com

文字列を実行時に決定されるNullable型に変換する方法は?

以下のコードがあり、文字列を文字列からも指定される型に変換する必要があります。

 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);

以下のエラーメッセージが表示されます。

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

それはどのようにうまく可能でしょうか?

醜い方法の1つは、次の場合に型がnull許容かどうかを確認することです。

    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);
    }

もっと良い方法はありますか?

ありがとう、

16
The Light

2つの問題があります。

まず、Convert.ChangeTypeプレーンはnull許容型をサポートしていません。

次に、たとえそうだったとしても、結果をボックス化する(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);
}
31
user743382

ほとんどのシナリオで機能する以下のジェネリックヘルパーメソッドを作成しました(ジェネリック型ではテストされていません)。

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;
}
11
The Light
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);
        }
    }
2
Hossein Shahabi

このようなもの?本当に動的に行う必要がない限り。

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

おそらく、自分の型が「null許容」型の1つであるかどうかを確認してから、ここで役立つものを見つけることができます。

文字列をnull許容型(int、doubleなど...)に変換します

1
Paddy