2011-11-14 8 views
9

ユーザ入力データを検証し、文字列値が実行時に指定された型に変換可能であることを確認する必要があります。必ずしも実際の変換を行う必要はありません。入力値が有効であることを確認するためのテストです。私は、このタイプの評価を行うクラスまたはメソッドを組み込みませんでしたが、もし私が欠けている場合は、教えてください。特定のバージョンのソリューションがあれば、私はC#4.0で作業しています。C#で文字列を指定された型に変換できるかどうかを調べる

このメソッドでは、「標準」型(組み込みの値データ型とString)のみを処理する必要があります。評価する必要がある唯一のカスタムタイプは、ライブラリで定義されている特定の列挙型です。

私は現在計量していますが、どちらも完璧ではないので、3つ目のオプション(または私が見逃したフレームワークに組み込まれたもの)があることを期待していました。 Solution#1のtry-catchを使用するのは間違っているので、私はソリューション#2に大きく傾いています。

ソリューション1Convert.ChangeType()のtry/catchで

public Boolean CheckType(String value, Type type) 
{ 
    try 
    { 
     var obj = Convert.ChangeType(value, type); 
     return true; 
    } 
    catch(InvalidCastException) 
    { 
     return false; 
    } 
    catch(FormatException) 
    { 
     return false; 
    } 
    catch(OverflowException) 
    { 
     return false; 
    } 
    catch(ArgumentNullException) 
    { 
     return false; 
    } 
} 

解決策2場合は、この方法でも数百またはと呼ばれることも

public Boolean CheckType(String value, Type type) 
{ 
    if (type == typeof(String)) 
    { 
     return true; 
    } 
    else if (type == typeof(Boolean)) 
    { 
     Boolean b; 
     return Boolean.TryParse(value, out b); 
    } 
    else if (type == typeof(Int32)) 
    { 
     Int32 i; 
     return Int32.TryParse(value, out i); 
    } 
    else if (type == typeof(Int64)) 
    { 
     Int64 l; 
     return Int64.TryParse(value, out l); 
    } 
    // similar code to check all other types 
    // (Int16, UInt32, UInt64, UInt16, Byte, SByte, Single, Double, Decimal, 
    // Enum, Char, DateTime) 
    . 
    . 
    . 
    . 
    . 
    else 
     throw new ArgumentException("Invalid type evaluation"); 

} 

/他のタイプチェックとチェーンとTryParse入力データがひどく混乱したり破損したりすると、短い間隔で何千回も繰り返されるので、繰り返しif/elseチェックがperformaのドラッグになるのではないかと心配していますnce(私は必ずしもこの時点で最適化しようとしているわけではありません、私は他のオプションも考慮しています)。

私が両方の解決策で持っているもう1つの問題は、両方とも実際に文字列値を期待される型の新しい値に変換することであり、どちらの場合でも結果を呑み込んでいます。

+0

@JeremyMcGee私はあなたがリンクされ、質問を見ましたが、私は実際に値を変換するために見ているわけではないから、ちょうど私が私の質問は必ずしも重複とは思わなかった、それが変換できることをテスト。 – psubsee2003

+0

@ psubsee2003:何かを変換することができるかどうかを確認する努力の量、実際にそれを変換するまでの量は、一般的にはかなり小さいです。 – Joe

+0

@Joe私はそのような感覚を持っていましたが、TryParseメソッドは非常に速いため、明白な例外はありません。変換前に最初にチェックする方法があるかどうか疑問でした。 – psubsee2003

答えて

3

MSDNのドキュメントに基づいて独自のエラー処理を追加してください。

+0

最後に、TypeConverterの回答に必要な例外処理としてこの勧告を出しました。避けるために。 – psubsee2003

14

TypeConverterと一般的な方法の使用を検討してください。これにより、多くのif文が回避されます。例外は、高価な(パフォーマンス)ですので、私はTryParse -wayを好むだろう

class Program 
    { 
     static T convert<T>(string s) 
     { 
      var typeConverter = TypeDescriptor.GetConverter(typeof(T)); 
      if (typeConverter != null && typeConverter.CanConvertFrom(typeof(string))) 
      { 
       return (T) typeConverter.ConvertFrom(s); 
      } 

      return default(T); 
     } 

     static void Main(string[] args) 
     { 
      int x = convert<int>("45"); 
     } 
    } 
+0

これは、タイプチェックの元の問題がどのように解決されるかを私は確信していません。コンバータに無効な値を渡すと(たとえば、int型の場合は「14.1」)、FormatExceptionがスローされます。私の最初の解決策はすでにそうしているので、なぜこれが望ましいのか分かりません。 – psubsee2003

+2

これはメソッドが汎用的であり、追加する新しいタイプごとに新しい** ifブロック**を必要としないため好ましい –

11

最近質問された別のquestionの私の最初のアイデアよりも良い解決策が見つかりました。

Parapura rajkumarはTypeConverterクラスで正しい軌道に乗っていましたが、非例外イベントのCanConvertFromメソッドの必要な例外処理は、回避しようとしていました。

TypeConverter.IsValidメソッドは私の問題を解決しましたが、IsValidメソッドはCanConvertFromメソッドと必要な例外処理のラッパーにすぎないため、理想的ではありません。

private Boolean CanCovert(String value, Type type) 
{ 
    TypeConverter converter = TypeDescriptor.GetConverter(type); 
    return converter.IsValid(value); 
} 
関連する問題