2012-01-04 24 views
2

直奔代碼:使用通用類型的分析方法?

class ArithmeticExpressionParser<T> : Parser 
{ 
    T num1, num2; 

    /* ......... */ 

    void ParseNumber() 
    { 
     string temp = String.Empty; 

     while (char.IsDigit(PeekNextToken())) 
     { 
      GetNextToken(); 
      temp += Token; 
     } 

     num1 = T.Parse(temp); // <<< the problem 
    } 

基本上,如果我使用intdouble我本來只是用int.Parse等。我已經試過鑄造num1 = (T)temp;,沒有工作。我怎樣才能做到這一點,而不必寫定製stringT函數?

+1

這種感覺就像你想的'IParsable'但'IConvertible'更具包容性(和存在) – Jodrell 2012-01-04 08:18:43

回答

9
class ArithmeticExpressionParser<T> : Parser where T : IConvertible 
{ 
    T num1, num2; 

    /* ......... */ 

    void ParseNumber() 
    { 
     string temp = String.Empty; 

     while (char.IsDigit(PeekNextToken())) 
     { 
      GetNextToken(); 
      temp += Token; 
     } 

     //num1 = T.Parse(temp); // <<< the problem 
     num1 = (T)Convert.ChangeType(temp, typeof(T)); 
    } 
} 

這是假設所有要轉換的類型,它們實現IConvertible,這將允許你把通用約束你的解析器類。如果不是所有類型都是可轉換的,則需要根據類型(雜亂)切換轉換方法。

如有必要,您也可以在自己的類型上實現IConvertible。有很多方法可以實現,但是如果你正在處理原始值,通常不需要太長的時間來實現。

http://msdn.microsoft.com/en-us/library/system.iconvertible.aspx

+0

通過使用Convert.ChangeType,您可以在T是值類型時進行裝箱。 – phoog 2012-01-04 14:43:27

3

使用Convert.ChangeType進行轉換。下面的代碼應與所有簡單類型的工作和

public static T Parse<T>(this string source) 
    {    
     if (typeof(T).IsSubclassOf(typeof(Enum))) 
     { 
      return (T)Enum.Parse(typeof(T), source, true); 
     } 

     if (!String.IsNullOrEmpty(source)) 
      return (T)Convert.ChangeType(source, typeof(T)); 

     return default(T); 
    } 
+0

Convert.ChangeType引起拳,然而,這可能會使用一組方法重載的避免。 – phoog 2012-01-04 14:45:58

+0

@phoog - 在這種情況下,方法重載不起作用,因爲類型的不同在於返回類型,而不是參數類型 - 參數始終是字符串,所以重載不適用。 – 2015-07-14 02:26:36

+0

@DaveRael好點,我用錯了詞。我想表明的是一組方法,它們在方法名中包含類型的名稱,例如'X.ParseDouble'和'X.ParseByte',它不會比'X.Parse '和' X.Parse '。 – phoog 2015-07-14 03:04:16