2009-03-15 22 views
6

2つのオブジェクトがあります。& B:Aはsystem.string、Bは一部の.netプリミティブ型(string、intなど)です。 Bの変換(解析)された値をAに代入する汎用コードを記述したいと思います。おかげで、アディ・バルダC#動的型変換

答えて

20

文字列変換を行うための最も実用的かつ汎用性の高い方法がTypeConverterである:

public static T Parse<T>(string value) 
{ 
    // or ConvertFromInvariantString if you are doing serialization 
    return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(value); 
} 

もっと種類がIConvertibleなどを実装するよりも、型コンバータを持って、あなたはまた、新しいタイプにコンバータを追加することができます - 両方、コンパイル時に時間;実行時に

[TypeConverter(typeof(MyCustomConverter))] 
class Foo {...} 

class MyCustomConverter : TypeConverter { 
    // override ConvertFrom/ConvertTo 
} 

ともあなたは(タイプのため、あなたが所有していない)必要がある場合:

TypeDescriptor.AddAttributes(typeof(Bar), 
    new TypeConverterAttribute(typeof(MyCustomConverter))); 
3

は、既存のSystem.ConvertクラスとIConvertibleインターフェースと何が問題なのですか?

+4

特に、Convert.ChangeTypeはあなたの後にある可能性があります。 – Noldorin

5

既に言及したように、System.ConvertとIConvertibleが最初の賭けになります。何らかの理由でそれらを使用できない場合(組み込み型の既定のシステムコンバージョンが適切でない場合など)、1つの方法として、各コンバージョンの代理人を保持する辞書を作成し、それを参照します必要なときに正しい変換を見つけます。

たとえば、あなたがXを入力する文字列から変換したいときには、以下を持つことができます:

using System; 
using System.Collections.Generic; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Console.WriteLine(SimpleConvert.To<double>("5.6")); 
     Console.WriteLine(SimpleConvert.To<decimal>("42")); 
    } 
} 

public static class SimpleConvert 
{ 
    public static T To<T>(string value) 
    { 
     Type target = typeof (T); 
     if (dicConversions.ContainsKey(target)) 
      return (T) dicConversions[target](value); 

     throw new NotSupportedException("The specified type is not supported"); 
    } 

    private static readonly Dictionary<Type, Func<string, object>> dicConversions = new Dictionary <Type, Func<string, object>> { 
     { typeof (Decimal), v => Convert.ToDecimal(v) }, 
     { typeof (double), v => Convert.ToDouble(v) } }; 
} 

明らかに、あなたはおそらく、カスタム変換ルーチンでもっと面白い何かをしたいと思うが、それはポイントを示しています。

+0

+1 - IConvertibleを変換不可能なタイプに拡張するための興味深いアプローチ。 –