динамически возвращать объект на основе строкового описания его типа

У меня есть база данных, в которой хранятся пользовательские данные в абстрактной строковой форме. Эти пользовательские вводы имеют столбец varchar, который описывает его тип (строка, десятичное число, логическое значение, раскрывающийся список и т. д.).

Теперь этот запрос отправляется во внешний интерфейс для отображения некоторых элементов ввода в браузере. Это прекрасно работает!

Однако, поскольку ввод настолько общий, значение также является varchar. Проблема, с которой я сталкиваюсь, заключается в том, что мне нужно выполнить некоторую проверку значения. (например, для некоторых строковых входных данных указано maxLength или регулярное выражение, десятичное число может иметь минимальное и максимальное значение).

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

Мне нужна функция, которая возвращает проанализированное значение в правильном типе.

поэтому у меня была бы функция, которая выглядит примерно так:

public {something here} ParseValue(InputObject object, string type) {
    // parse here based on type
    // InputObject has a few properties like value, min, max, regex etc
    // all as a string. 
    // for instance if type is datetime I want to return a new object
    // which has parsed the value, min and max as datetime. 
    // it should also be possible for the type to be decimal and min, max
    // and value should be decimal in the outputObject
}

Я исхожу из динамически типизированного фона, поэтому я понятия не имею, как сделать что-то подобное. или даже если это возможно.

любая помощь приветствуется!


person rg13376077    schedule 17.08.2016    source источник
comment
{something here} должно быть просто object. Остальное должно быть простым — просто делайте то, что вы делаете в среде с динамическими типами.   -  person adv12    schedule 17.08.2016
comment
Здесь можно использовать возвращаемый тип dynamic.   -  person zdimension    schedule 17.08.2016
comment
Есть ли причина, по которой вы используете этот подход вместо правильной модели данных? Просто любопытно... как по моему опыту, обычно это заканчивается плохо и в конечном итоге требует больше времени на исправление ошибок, чем на то, чтобы сделать это правильно в любом случае.   -  person Milney    schedule 17.08.2016
comment
@Milney Я не создавал модель данных, но это большая модель данных, из которой это лишь крошечная часть. Если бы нам пришлось явно разделить это на уровне модели данных, это добавило бы 30+ таблиц. Все они будут выполнять одну и ту же функциональность, за исключением того, что 1 для целых чисел, один для даты и времени, один для десятичных знаков и т. д.   -  person rg13376077    schedule 18.08.2016


Ответы (2)


Вам было бы лучше, если бы вы не пытались напрямую оценить тип по типу базы данных и вместо этого сохранили «реальный» тип в отдельном столбце БД. За исключением случаев, когда вы создаете связь между типами С# и типами баз данных, потому что тогда вы можете сделать что-то вроде этого:

String val = "123";
String type = "System.Int32";
Type tempType = Type.GetType(type);
if (tempType == null)
  return null;
dynamic result = Convert.ChangeType(val, tempType);

Конечно, это применимо и к граничным значениям. Обратите внимание, что Convert.ChangeType работает только для очень популярных типов и не является универсальным, и что он генерирует исключение, если что-то не работает, что также необходимо отловить.

person prizm1    schedule 17.08.2016

Что вы могли бы сделать, так это создать interface IValidatable, который определяет такой метод, как Validate(). Затем вы можете использовать это как тип возвращаемого значения. Затем вы просто анализируете свое значение с помощью переключателя (возможно, делегируете это какому-то методу или классу) в реализацию IValidatable. Например.

public interface IValidatable {
     bool Validate();
}


public class ValidateableInteger : IValidatable {
     private int _value;
     public ValidateableInteger(int i) {
          _value = i;     
     }

     bool Validate() {
          //code where you validate your integer.
     }
}

Обратите внимание, что это не очень гибко, так как у вас есть только 1 метод с именем validate, хотя, очевидно, вы можете определить несколько более общих методов, которые могут реализовывать различные проверки.

Кроме того, вы можете создавать более конкретные интерфейсы, например. числовые типы (например, IValidateableNumeric и ValidateableInt : IValidateableNumeric)

Обратите внимание, что вы в основном вводите здесь свой ввод, что довольно странно и не нужно, учитывая тот факт, что вы можете просто работать с типизированными данными для начала.

В конце концов, я бы отговаривал людей от такого обхода системы типов. В этом случае особенно много способов создания элементов формы при использовании типизированных данных (ознакомьтесь с механизмом шаблонов Razor).

person Glubus    schedule 17.08.2016