解析を使用して文字列を任意のタイプに変換する汎用のParse()関数はありますか?


91

文字列を、ジェネリック戻り値の型のような、intまたはdateそれにlong基づくジェネリック型に変換したいと思います。

基本的に、Parse<T>(String)そのような関数はタイプのアイテムを返しますT

たとえば、intが渡された場合、関数はint.parse内部で実行する必要があります。

回答:


132

System.Convert.ChangeType

あなたの例のように、あなたはすることができます:

int i = (int)Convert.ChangeType("123", typeof(int));
DateTime dt = (DateTime)Convert.ChangeType("2009/12/12", typeof(DateTime));

「ジェネリック戻り値の型」の要件を満たすために、独自の拡張メソッドを作成できます。

public static T ChangeType<T>(this object obj)
{
    return (T)Convert.ChangeType(obj, typeof(T));
}

これにより、次のことが可能になります。

int i = "123".ChangeType<int>();

かっこいいですが、ChangeTypeという名前の奇妙なことなので、この関数はある種のキャストを実行し、解析は行わないと思います
Karim

7
MSDNによると、これはソースオブジェクトで適切な変換メソッドを見つける単なるラッパーであり、IConvertibleインターフェイスを実装する必要があります。
アニ

実装するIConvertable必要がある場合は、、TつまりT ChangeType<T>(this object obj) where T : IConvertable?も制約するべきではありません。
リアム

2
@Liam:いいえ、そうobjする必要IConvertibleがありますが、コンパイル時にそれを指定する方法はありません。
アニ2015

失敗した場合にnullまたはfalseを返すTryChangeTypeのようなものが必要な場合は?例外をキャッチすることによってのみ?
絶望的な2015年

21

このスレッドで答えるには遅すぎるようです。しかし、これが私の実装です:

基本的に、ObjectクラスのExtentionメソッドを作成しました。null許容型、クラス、構造体など、すべての型を処理します。

 public static T ConvertTo<T>(this object value)
           {
               T returnValue;

               if (value is T variable)
                   returnValue = variable;
               else
                   try
                   {
                       //Handling Nullable types i.e, int?, double?, bool? .. etc
                       if (Nullable.GetUnderlyingType(typeof(T)) != null)
                       {
                           TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
                           returnValue = (T) conv.ConvertFrom(value);
                       }
                       else
                       {
                           returnValue = (T) Convert.ChangeType(value, typeof(T));
                       }
                   }
                   catch (Exception)
                   {
                       returnValue = default(T);
                   }

               return returnValue;
           }

私見これは「null許容」の側面も含まれているため、より良い答えです
Ole Albers

TypeDescriptornull許容型とConvert.ChangeType非null許容型に使用している特定の理由はありますか?このtryブロック全体はTypeConverter2行のコードにしか減らすことができず、null許容と非null許容の両方で機能します。
IMujagic


8

プラネイの答えのよりクリーンなバージョン

public static T ConvertTo<T>(this object value)
{
    if (value is T variable) return variable;

    try
    {
        //Handling Nullable types i.e, int?, double?, bool? .. etc
        if (Nullable.GetUnderlyingType(typeof(T)) != null)
        {
            return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(value);
        }

        return (T)Convert.ChangeType(value, typeof(T));
    }
    catch (Exception)
    {
        return default(T);
    }
}

0

.NETには、あるタイプのオブジェクトを別のタイプに変換するための規則がいくつかあります。

ただし、これらの方法は通常よりもはるかに遅く、T.Parse(string)ボクシングを引き起こし、単一の値を変換するたびに多くの割り当てが必要になります。

以下の場合で、valueString、私は、リフレクションを使用したタイプの、適当な、静的解析方法を見つけ、それを呼び出してラムダ式を構築し、将来の使用のためにコンパイルされたデリゲートを(参照キャッシュするために選んだこの回答例を)。

また、タイプに適切な解析方法がない場合は、上記の方法にフォールバックします(Readmeのパフォーマンスセクションを参照)。

var v = new ValueString("15"); // struct
var i = v.As<int>(); // Calls int.Parse.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.