2012-02-24 32 views
15

我有下面的代碼和我需要一個字符串轉換爲一個類型,也是從字符串指定:如何將字符串轉換爲運行時確定的可空類型?

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]]'. 

如何將這項很可能嗎?

我知道一個醜陋的方式是檢查的類型是否爲空,如果使用:

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

會不會有什麼更好的辦法?

謝謝,

回答

29

有兩個問題。

首先,Convert.ChangeType只是普通的不支持可爲空的類型。

其次,即使是這樣,通過對結果進行裝箱(將其分配給object),您已經將其轉換爲DateTime

你可以特殊情況下可空類型:

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 <>)部分將覆蓋該部分;不是嗎? – 2012-02-24 12:09:30

+2

@William'GetGenericTypeDefinition()'如果類型不是泛型的,則拋出異常。 – hvd 2012-02-24 13:41:42

1

是這樣的?除非你真的需要動態地做。

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

也許你可以檢查,看看你的類型是「可空」的類型之一,那麼也許你可以在這裏找到一些有用的東西:

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

+0

我可以」 t指定DateTime,它在運行時確定。 – 2012-02-24 09:33:56

+0

'return new DateTime?();'應該被'return null;'替換。 – ken2k 2012-02-24 09:35:09

+0

也許如果你可以提供一些關於你正在做什麼而不是你現在正在做的事情的更多信息,我們可以提供建議嗎? – Paddy 2012-02-24 09:36:42

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

謝謝。這是最優雅的工作解決方案。 – 2017-02-27 13:42:56

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); 
     } 
    } 
相關問題