根据其类型的字符串描述动态返回一个对象

时间:2016-08-17 14:30:56

标签: c# .net typing

我有一个数据库,以抽象的字符串形式存储用户输入。这些用户输入有一个varchar列,用于描述其类型(字符串,十进制,bool,下拉等)。

现在这个get发送到前端以在浏览器中显示一些输入元素。这很棒!

然而,由于输入是如此通用,因此该值也是varchar。我面临的问题是我需要对值进行一些验证。 (例如,某些字符串输入指定了maxLength或regex,小数可以具有最小值和最大值)。

所以一旦我收回用户输入的值,就是字符串格式,我想将其解析为正确的本机类型,以便我可以开始验证它。

我想要一个函数,它以正确的类型返回解析后的值。

所以我会有一个像这样的函数:

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
}

我来自动态类型的背景,所以我不知道如何做这样的事情。或者即使有可能。

任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:1)

如果您不直接尝试通过Database-Datatype评估类型,而是将“real”类型存储在单独的DB-Column中,那么您最好。除非你在C#-Types和Database-Types之间建立一个关联,因为你可以这样做:

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仅适用于非常受欢迎的类型,并且不是普遍可用的,并且如果还有一些失败需要捕获它,它会抛出异常。

答案 1 :(得分:0)

您可以做的是创建interface IValidatable来定义Validate()之类的方法。然后你可以使用它作为返回类型。然后,您只需使用开关(可能将此委托给某个方法或类)解析为IValidatable的实现。 E.g。

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.
     }
}

请注意,这不是很灵活,因为您只有一个名为validate的方法,但显然您可以定义多个可以实现不同验证的更通用的方法。

此外,您可以为例如创建更具体的界面数字类型(例如IValidateableNumericValidateableInt : IValidateableNumeric

请注意,你基本上是在这里输入你的输入,这有点奇怪和不必要,因为你可以开始使用类型数据。

最后,我会阻止人们以这种方式绕过类型系统。在这种情况下,特别是在使用类型化数据时有很多更好的方法来创建表单元素(检查Razor模板引擎)。