LINQ表达式使用不同的对象类型创建一个数组

问题描述:

我正在做一些解析用户输入,在这里我需要解析应该是某些类型的参数数组。LINQ表达式使用不同的对象类型创建一个数组

在解析的时候,我不知道每个参数应该是哪个类型,但它可以被评估为任何类型。所以,我决定暂时将它们存储在一个对象数组中。但是,当我尝试做这样的事情:

NewArrayExpression returnValue = Expression.NewArrayInit(typeof(object), expressionList); 

我得到以下异常:类型“System.Int32”的表达式不能用于初始化类型的数组“System.Object的”。

也就是说,我猜想,因为没有隐式拳击正在发生。所以我自己装箱:

expressionList.Add(Expression.TypeAs(expression, typeof(object))); or 
expressionList.Add(Expression.Convert(expression, typeof(object))); 

到目前为止很好:我得到了一个数组中的各种类型的对象列表。

但是,当我终于得到想要的类型,我尝试将所有从上数组中的值的那种类型(可以说是类型为usualy一个int),我把它转换:

Expression.Convert(expr, typeof(int)); or 
Expression.Unbox(expr, typeof(int)); 

这是当expr是actualy一个字符串“AAAAA”这两个命令的调试视图:

(System.Int32)((System.Object)"aaaaa") 

现在,这里存在我的问题:这会不会抛出异常。但是当表达式最终编译完成时。我的意思是,字符串不是int。

也许这真的不应该抛出异常,我不知道。但这对我不起作用。

这有没有办法解决?

编辑:的代码看起来是这样的:

static Expression InArguments(ParameterExpression pe, string[] arguments) 
{ 
    List<Expression> listaExpr = new List<Expression>(); 
    foreach (string s in arguments) 
    { 
     Expression expression = Complete(pe, s); // evaluate argument 
     // listaExpr.Add(Expression.Convert(expression, typeof(object))); 
    } 
    return Expression.NewArrayInit(typeof(object), listaExpr); 
} 
+0

为什么你认为你需要的对象存储在一个数组?您能否展示整个表达式的示例,尤其是如何使用数组? – svick 2012-03-11 19:15:35

+0

那么,我想模仿SQL IN操作符。用户应该输入如下内容: Item.Code IN [1,2,3]或Partner.Name IN [“aa”,“bb”]其中,代码将被动态评估为int,Name将评估为字符串。 但是,这是允许的:Item.Code IN [1,2,Partner.GetTopItem()] – 2012-03-11 19:27:04

+0

所以,我需要评估IN运算符的所有参数,它可以导致简单类型(int,string,decimal),但也可能导致我的模型中的任何类型,或者它们的集合。之后,我将它们转换为左操作数的类型。我不知道,也许我太过于复杂 – 2012-03-11 19:36:50

在我看来,你知道的类型,它只是你计算它为时已晚。如果你能改变这一点,它会解决你的问题。然后,该方法是这样的:

static Expression InArguments(
    ParameterExpression pe, string[] arguments, Type itemType) 
{ 
    List<Expression> listaExpr = new List<Expression>(); 
    foreach (string s in arguments) 
    { 
     Expression expression = Complete(pe, s, itemType); // evaluate argument 
     listaExpr.Add(expression, typeof(object)); 
    } 
    return Expression.NewArrayInit(itemType, listaExpr); 
} 

并调用它可能看起来像这样的代码:

Expression inProperty = InProperty(…); 
Expression inArguments = InArguments(pe, arguments, inProperty.Type); 

Expression result = Expression.Call(containsMethod, inArguments, inProperty); 

@svick

啊,这是我的问题。我的整个系统设置为独立解析左和右操作数,然后检查它们之间的可转换性。所以,我想我的IN运算符的右操作数返回对象数组的表达式,所以我可以测试每个对象的可转换性,但在我看来,一旦我将它们转换为对象,它们可转换为任何东西? 。

所以,我决定返回以下从我的右操作数的表达式:

static Expression InArguments(ParameterExpression pe, string arguments) 
    { 
     string substr = arguments.Substring(1, arguments.Length - 2); 
     string[] arr = substr.Split(','); 
     return Expression.Constant(arr, typeof(string[])); 
    } 

再后来:

static Expression InOperator(Expression left, Expression right, ParameterExpression pe) 
    { 
     Expression finalexpr = null; 

     // this solved my problem. 
     string[] args = Expression.Lambda<Func<string[]>>(right).Compile()(); 

     foreach (string s in args) 
     { 
      Expression converted = null;     

      try 
      { 
       Expression expr = Complete(pe, s); 
       converted = Expression.Convert(expr, (left as Expression).Type); 
      } 
      catch 
      { 
       throw; 
      } 

      if (finalexpr == null) finalexpr = Expression.Constant(false); 
      finalexpr = Expression.OrElse(finalexpr, Expression.Equal(left, converted)); 
     } 

     return finalexpr; 
    } 

我forwared我的论点的地方,我实际上可以参考点左操作数类型,在string []的常量表达式内部,然后编译它以获取我的字符串参数。

但尽管如此,我也喜欢,如果我能一个对象数组中转发...