2014-10-01 2 views
1

У меня есть необходимость изучить, чтобы увидеть, если объект может быть преобразован в определенной ТипДанных или нет, и пришел с этим:Dynamic TryParse для всех типов данных

public static bool TryParseAll(System.Type typeToConvert, object valueToConvert) 
{ 

    bool succeed = false; 

    switch (typeToConvert.Name.ToUpper()) 
    { 
     case "DOUBLE": 
      double d; 
      succeed = double.TryParse(valueToConvert.ToString(), out d); 
      break; 
     case "DATETIME": 
      DateTime dt; 
      succeed = DateTime.TryParse(valueToConvert.ToString(), out dt); 
      break; 
     case "INT16": 
      Int16 i16; 
      succeed = Int16.TryParse(valueToConvert.ToString(), out i16); 
      break; 
     case "INT": 
      Int32 i32; 
      succeed = Int32.TryParse(valueToConvert.ToString(), out i32); 
      break; 
     case "INT32": 
      Int32 i322; 
      succeed = Int32.TryParse(valueToConvert.ToString(), out i322); 
      break; 
     case "INT64": 
      Int64 i64; 
      succeed = Int64.TryParse(valueToConvert.ToString(), out i64); 
      break; 
     case "BOOLEAN": 
      bool b; 
      succeed = Boolean.TryParse(valueToConvert.ToString(), out b); 
      break; 
     case "BOOL": 
      bool b1; 
      succeed = bool.TryParse(valueToConvert.ToString(), out b1); 
      break; 
    } 

    return succeed; 
} 

мне интересно, есть ли другими способами? Что более динамично и эффективно?

Спасибо!

+3

бы лучше в [CodeReview.SE]? –

+1

Найти метод «TryParse» с отражением, если не найден, исключить исключение, иначе компилируйте делегата, используя «Linq.Expressions», Cache it, Выполняйте его всякий раз, когда вызывается метод. –

ответ

1

Вы должны использовать класс TypeDescriptor:

public static T Convert<T>(this string input) 
{ 
    var converter = TypeDescriptor.GetConverter(typeof(T)); 
    if(converter != null) 
    { 
     //Cast ConvertFromString(string text) : object to (T) 
     return (T)converter.ConvertFromString(input); 
    } 
    return default(T); 
} 

это, конечно, будет сгенерировано исключение, если преобразование не может, так что вы хотите попробовать/поймать его.

+1

Вот почему он использует TryParse. Чтобы вернуть логическое значение, не выбрасывать исключение. – Marco

+0

Этот код не отвечает на вопрос. Очевидно, что вопрос связан с анализом данных без исключений. – Mick

3

Вот моя версия общего метода TryParse. Я считаю, что вы можете использовать эту версию тоже:

double pi; 
if(ValueTypeHelper.TryParse("3.14159", out pi)) { 
    // .. pi = 3.14159 
} 
... 
string eStr = "2.71828"; 
float e; 
if(eStr.TryParse(out e)) { 
    // .. e = 2.71828f 
} 
... 
static class ValueTypeHelper { 
    static IDictionary<Type, Delegate> cache = new Dictionary<Type, Delegate>(); 
    public static bool TryParse<T>(this string valueStr, out T result) { 
     Delegate d = null; 
     if(!cache.TryGetValue(typeof(T), out d)) { 
      var mInfos = typeof(T).GetMember("TryParse", MemberTypes.Method, BindingFlags.Static | BindingFlags.Public); 
      if(mInfos.Length > 0) { 
       var s = Expression.Parameter(typeof(string)); 
       var r = Expression.Parameter(typeof(T).MakeByRefType()); 
       d = Expression.Lambda<TryParseDelegate<T>>(
        Expression.Call(mInfos[0] as MethodInfo, s, r), s, r).Compile(); 
      } 
      cache.Add(typeof(T), d); 
     } 
     result = default(T); 
     TryParseDelegate<T> tryParse = d as TryParseDelegate<T>; 
     return (tryParse != null) && tryParse(valueStr, out result); 
    } 
    delegate bool TryParseDelegate<T>(string valueStr, out T result); 
} 
+0

Извините за поздний ответ, я сразу проверю это и дам вам знать через мгновение – NeedAnswers

1

Я объединил обе DmitryG-ые лет и RezaRahmati Предложенных решений:

static class GenericValueConverter 
{ 
    public static bool TryParse<T>(this string input, out T result) 
    { 
     bool isConversionSuccessful = false; 
     result = default(T); 

     var converter = TypeDescriptor.GetConverter(typeof(T)); 
     if (converter != null) 
     { 
      try 
      { 
       result = (T)converter.ConvertFromString(input); 
       isConversionSuccessful = true; 
      } 
      catch { } 
     } 

     return isConversionSuccessful; 
    } 
} 

void Main() 
{ 
    double pi; 
    if (GenericValueConverter.TryParse("3,14159", out pi)) //Use right decimal point seperator for local culture 
    { 
     pi.Dump(); //ConsoleWriteline for LinqPad 
     //pi=3,14159 
    } 

    string dtStr = "2016-12-21T16:34:22"; 
    DateTime dt; 
    if (dtStr.TryParse(out dt)) 
    { 
     dt.Dump(); //ConsoleWriteline for LinqPad 
     //dt=21.12.2016 16:34:22 
    } 

    string guidStr = "D430831B-03B0-44D5-A971-4E73AF96B5DF"; 
    Guid guid; 
    if (guidStr.TryParse(out guid)) 
    { 
     guid.Dump(); //ConsoleWriteline for LinqPad 
     //guid=d430831b-03b0-44d5-a971-4e73af96b5df 
    } 
} 
Смежные вопросы