ChangeType, Convert - Преобразование из одного типа в другой - PullRequest
1 голос
/ 08 ноября 2010

Я рассмотрел различные варианты, которые, по-видимому, доступны в .NET Framework (я думаю).В частности, я посмотрел на 1. TypeConverter 2. Convert.Toxxx 3. Convert.ChangeType

Каждый из них по тем или иным причинам у меня не работает.Я весьма удивлен, что в платформе .NET, похоже, нет решения для такого рода вещей.Я предполагаю, что я не единственный, кому это нужно;)

Вот что я пытаюсь сделать.По сути, у меня есть куча HTML-форм, которые используются в приложении.Эти формы позволяют пользователям вводить данные (очевидно), и мне нужно извлекать эти данные в различные типы данных.

Эти типы данных являются простыми типами, примитивными типами, типами значений, ссылочными типами и пользовательскими ссылочными типами.Другими словами: 1. Int32, Int64, double, decimal, DateTime и т. Д. 2. Int32 [], double [], string [] и, возможно, другие массивы примитивных типов 3. различные пользовательские объекты DTO, которые имеют вышеуказанные типы в качестве свойств.

«Ввод» обычно выполняется в виде строки, так как я нахожусь в стране Http.Чтобы дать вам представление о том, почему существующие решения не работают для меня, взгляните на следующие «строковые» входы, которые необходимо преобразовать

  1. «1,234» -> Int32
  2. "$ 1,234" -> Int32
  3. "$ 1,234" -> Int32
  4. "" -> Int32
  5. "1,2,3,4,5" ->Int32 []
  6. "0" ИЛИ "false" ИЛИ "False" ИЛИ "off" -> Boolean false

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

Ответы [ 2 ]

1 голос
/ 09 ноября 2010

Джеки,

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

@ Крис, эти правила не произвольны ни одним выстрелом воображения.На самом деле они очень распространены, когда дело доходит до пользовательского ввода, особенно через Интернет.На самом деле, логические преобразования также довольно распространены, учитывая, что флажки в ASP.NET возвращаются вкл / выкл (по некоторым причинам).

У вас есть несколько вариантов.Один - это упрощенный подход, а другой - расширяемое решение.Все начинается с того, как вы хотите использовать эту функцию в своем приложении.Поскольку вы не пролили много света на то, что вы делаете в данный момент или как бы вы хотели это сделать, я позволил себе сделать несколько предположений.

Основное предположение заключается в том, чточто значения приходят к вам через Request.Form или Request.QueryStrings (оба из которых являются NameValueCollections, которые могут содержать несколько значений для данного имени).

Предположим, вам нужен метод с именем ChangeType, который даетимя параметров и тип, на который вы хотите изменить его, вернут значение в качестве требуемого типа.Таким образом, сигнатура метода может выглядеть следующим образом:

public T ChangeType<T>(string parameterName, T defaultValue = default(T))

И поэтому вы можете использовать его так:

int someId = ChangeType<int>("id", -1);

Таким образом, значение переменной someId будетлибо значение, извлеченное из Request.Form или Request.QueryStrings в форме типа int (если оно существует), либо -1, если его нет.

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

    static T ChangeType<T>(string value) where T: struct
{
  Type typeOft = typeof(T);
  if (String.IsNullOrEmpty(value.Trim()))
    return default(T);
  if (typeOft == typeof(Int32))
    return (T)ConvertToInt32(value);
  else if (typeOft == typeof(Int64))
    return (T)ConvertToInt64(value);
  else if (typeOft == typeof(Double))
    return (T)ConvertToDouble(value);
  else if (typeOft == typeof(Decimal))
    return (T)ConvertToDecimal(value);
  return default(T);
}

static object ConvertToInt32(string value)
{
  return Int32.Parse(value,
    NumberStyles.Currency ^ NumberStyles.AllowDecimalPoint);
}

static object ConvertToInt64(string value)
{
  return Int64.Parse(value,
    NumberStyles.Currency ^ NumberStyles.AllowDecimalPoint);
}

static object ConvertToDouble(string value)
{
  return Double.Parse(value, NumberStyles.Currency);
}

static object ConvertToDecimal(string value)
{
  return Decimal.Parse(value, NumberStyles.Currency);
}

Если вам нужно обрабатывать больше типов, просто реализуйте требуемый метод (например, ConvertToInt32) и добавьте еще одно условие else в метод ChangeType<T>, и все готово.

Теперь, если вы ищете расширяемое решение, чтобы вы могли добавить дополнительные возможности без необходимости изменять основной код и иметь возможность обрабатывать ваши собственные пользовательские типы, тогда, пожалуйста, взгляните на мой блог.[ChangeType - Изменение типа переменной в C #] [1] http://www.matlus.com/2010/11/changetypet-changing-the-type-of-a-variable-in-c/

Надеюсь, это поможет.

1 голос
/ 08 ноября 2010

Все примитивные типы, такие как int и bool, имеют статический метод TryParse , который вы можете использовать для них. Это сделает ваши вещи Int32 для вас:

Int32 temp = 0;
Int32.TryParse(myStringInput, out temp);

TryParse() возвращает логическое значение, указывающее, был ли анализ успешным или нет, поэтому вы можете проверить это и принять меры, если хотите, или просто сделать, как я делал выше, и иметь значение по умолчанию, если TryParse выходит из строя. TryParse особенно полезен, потому что он не выдает исключение в случае сбоя (он просто возвращает false).

bool.TryParse() не собирается напрямую переводить числовое значение 0 как false - сначала нужно привести его к строке:

bool x = true;
bool.TryParse(0.ToString(), out x);
Console.WriteLine("x is {0}", x);

Для перевода значения строки off или on в логическое значение потребуется ваша собственная функция для его интерпретации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...