2016-02-25 55 views
1

我有一個List<Type>,它們表示來自自定義腳本語言的基於文本的命令的簽名。我試圖確定如何解析String[]List<object>在對象類型關聯到List<Type>。基本上給了Type t我想嘗試投一個String sType給定一個類型和一個字符串,你可以嘗試將該字符串轉換爲該類型而不會干擾該類型?

到目前爲止,我有這個

Type t = ...; 
String s = ...; 
if(Convert.ChangeType(s, t) != null) 
{ 

} 

我懷疑是想Convert.ChangeType更正確後。它的意思是簡單地改變給定對象的類型,而不是「解析」它。看到你不能簡單地做(double)"ImAString"我會假設這個方法將被用於在「直接」可鑄造的對象類型之間進行轉換。

是否有此任何通用的解決方案?或者是做這個創建於給定Typeswitch每個個案中解析(在未來開關最有可能缺少類型)的唯一途徑?

編輯:此外,返回類型ChangeType是對象。我假設如果我要做retObjectFromChange is double會是真的(假設我將類型改爲雙精度型)?

+0

'Convert.ChangeType()'好像是一種正確的方法。您可以將字符串轉換爲雙精度,但如果轉換失敗,則可能會拋出異常。即:'「1.001」'可以正常工作,而「ImAString」會拋出異常。 – ebyrob

回答

2

Convert.ChangeType()將解析字符串到數字的時候可能就不是有效的數字的字符串拋出異常。

注意:如果你要自己的自定義類型之間的轉換有很多,你可能需要使用一個TypeConverter代替。 (TypeConverter將到原始的類型,如string都轉換時獲得更好的工作。)

參見: Convert System.String generically to any complex type using "Convert.ChangeType()"

編輯: 是,Convert.ChangeType("1.02", typeof(double)) is double應該評估爲true,假設沒有拋出異常。

+0

我目前計劃只使用原始類型,可能還有一個「枚舉」或兩個。我從答案中假設這些工作會很好。 //從鏈接問題,特別是我們的救星Jon Skeet的答案(http://stackoverflow.com/a/5401888/2985796)將解決方案轉換爲更復雜的類型是在這些類型中實現'IConvertable'接口嗎? //我也對這個問題做了一個小小的修改,如果你能解決這個問題,我認爲它是一個簡單的答案? – KDecker

+0

'IConvertable'的問題在於,即使很容易從Foo轉換爲字符串,也很難從字符串轉換爲Foo。 (如果這是有道理的) – ebyrob

+0

假設我實現了實現'IConvertable'的類,它應該是「容易的」。我只需確保將類對象定義爲字符串是確切的,儘管它可能會成長爲一些非常無知的字符串。這是你的意思不容易嗎? – KDecker

2

這是我目前的執行情況。我發現了Guid,DateTime,枚舉和可空值是我的邊緣情況。我把邏輯處理空字符串和空值。我對某些原語進行了特定的處理,因爲我發現TypeConverter比較慢,這是我的一般情況。

public object GetValue(string readerValue, Type conversionType) 
    { 
     // if the type is a string, just return the value with no conversion 
     if (conversionType == typeof(string) || conversionType == typeof(object)) 
     { 
      return readerValue; 
     } 

     // if the field has a value try to cast it 
     if (!string.IsNullOrWhiteSpace(readerValue)) 
     { 
      readerValue = readerValue.Trim(); 

      if (conversionType.IsEnum) 
      { 
       return Enum.Parse(conversionType, readerValue); 
      } 
      else 
      { 
       Type underlyingType = Nullable.GetUnderlyingType(conversionType) ?? conversionType; 

       if (underlyingType == typeof(int)) 
       { 
        return int.Parse(readerValue); 
       } 
       else if (underlyingType == typeof(bool)) 
       { 
        return bool.Parse(readerValue); 
       } 
       else if (underlyingType == typeof(DateTime)) 
       { 
        return DateTime.Parse(readerValue); 
       } 
       else if (underlyingType == typeof(double)) 
       { 
        return double.Parse(readerValue); 
       } 
       else if (underlyingType == typeof(long)) 
       { 
        return long.Parse(readerValue); 
       } 
       else if (underlyingType == typeof(Guid)) 
       { 
        return Guid.Parse(readerValue); 
       } 
       else 
       { 
        // GetConverter and ConvertFrom are both slow, so only use it in a fallback 
        TypeConverter converter = TypeDescriptor.GetConverter(underlyingType); 
        return converter.ConvertFrom(readerValue); 
       } 
      } 
     } 
     // return null for nullable generic primitives 
     else if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition() == typeof(Nullable<>)) 
     { 
      return null; 
     } 
     // return the default value for non nullable primitive types 
     else if (conversionType.IsValueType) 
     { 
      return Activator.CreateInstance(conversionType); 
     } 
     // return null for reference types 
     else 
     { 
      return null; 
     } 
    } 
+0

這是一個非常完整的解決方案。 – KDecker

+0

如果您發現任何我沒有處理的邊緣案例,請告訴我。我打算在某個時候在發佈中使用它,所以我很樂意提前知道有關問題。 –

+0

實際上,我有一些生產代碼,其工作方式與您的代碼非常相似,主要是出於性能原因。我實現了將各種對象轉換爲字符串的兩種方法。這是一個非常實用的方法。 – ebyrob

相關問題