2016-06-23 2 views
1

Я пытаюсь преобразовать строку универсального типа, такие как:Анализировать Строка шаблонного типа

Int16, Int32, Int64, Double, Boolean, DateTime, Guid, ... 

Я создал следующее, который работает отлично подходит для Ints и булевы:

public static Boolean TryParse<T>(String source, out T value) { 

    TypeConverter converter = TypeDescriptor.GetConverter(typeof(T)); 

    try { 

    value = (T)converter.ConvertFromString(source); 
    return true; 

    } catch { 

    value = default(T); 
    return false; 

    } 

} 

Однако , он не работает на парном, финики, ...

Без использования общего TryParse я был в состоянии сделать его работу:

List<String> values = new List<String> { "1", "true", "2.125", "C", "20-08-2016" }; 

    List<Object> parsed = new List<Object>(); 

    foreach (String value in values) { 

    Int32 i; 
    Boolean b; 
    Double d; 
    DateTime dt; 

    if (Int32.TryParse(value,NumberStyles.Integer, CultureInfo.InvariantCulture, out i)) { 
     parsed.Add(i); 
    } else if (Boolean.TryParse(value, out b)) { 
     parsed.Add(b); 
    } else if (Double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out d)) { 
     parsed.Add(d); 
    } else if (DateTime.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out dt)) { 
     parsed.Add(dt); 
    } else { 
     String s = value; 
     parsed.Add(s); 
    } 

    } 

Но, как вы можете видеть, я передаю несколько параметров каждому TryParse, который, как представляется, необходим специально для парного разряда и DateTimes.

Проблема в том, что в системе, которую я создаю, я не уверен в том, что я буду разбирать строку, поэтому я использую Generics.

Как это сделать?

Пример

Модульное тестирование для разбора двойной:

public void TryParse_ParseStringToDouble() { 

    Double result; 

    StringExtensions.TryParse("2040.345434", out result); 

    Assert.Equal(result, 2040.345434); 

} 

С этим я получаю исключение на TryParse:

2040.345434 is not a valid value for Double. 

Я думаю, это потому, что я должен использовать " 2040,345434 "на машине, над которой я работаю ... Но мне все равно хотелось бы работать ...

+0

Я попробовал 'double', и ваш общий' TryParse 'отлично работает для меня. – Quantic

+0

Как вы используете свою версию 'TryParse'? можете ли вы привести пример? –

+0

http://dejanstojanovic.net/aspnet/2015/february/convert-string-to-any-type-that-implements-tryparse-method/ –

ответ

1

Если вы хотите конвертировать, вы можете использовать следующий метод.

public T ConvertToType<T>(string input) 
{ 
    return (T)Convert.ChangeType(input, typeof(T)); 
} 

Использование:

string input = "06/23/2016"; 
DateTime date = ConvertToType<DateTime>(input); 
+0

Получил ошибку «Строка ввода не была в правильном формате». при использовании вашего кода и разбора двойного «20.405» –

+0

Вы изменили тип? Я просто сделал тот же тест, и он отлично работал. «20.405» не преобразуется в 'DateTime'. 'double myDouble = ConvertToType (ввод);' –

+0

Да, я изменил тип ... Возможно, если вы попробуете «20,405» (обратите внимание на запятую), вы получите ту же ошибку, которую я получаю с «20.405». Нет? –

0

То же, что Мэтт Rowland, но ручки nullables.

public static T ConvertToType<T>(object value) 
{ 
     var targetType = typeof(T); 
     var conversionType = Nullable.GetUnderlyingType(targetType) ?? targetType; 
     return (T)Convert.ChangeType(value, conversionType); 
    }