2012-01-04 20 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 
    } 

、私はintまたはdoubleを使用していた場合、私は、私は動作しませんでしたnum1 = (T)temp;を、キャスト試してみただけint.Parseなどを使用しています。 〜Tのカスタム機能を使わなくても、どうすればいいですか?

+1

はIConvertible'はより包括的である(と存在する) – Jodrell

答えて

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

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は、メソッドのオーバーロードのグループを使用して回避することができた、しかし、ボクシングを起こし '' IParsable'をしたいが。 – phoog

+0

@phoog - 型の違いは戻り値の型であり、パラメータの型ではないため、この場合はメソッドのオーバーロードが機能しません。パラメータは常に文字列なのでオーバーロードは適用されません。 –

+0

@DaveRael良い点、私は間違った言葉を使いました。私が指摘しようとしたのは、 'X.ParseDouble'や' X.ParseByte'のように、メソッド名に型名を含むメソッド群でした。これは 'X.Parse 'と ' X.Parse '。 – phoog

関連する問題