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);
}
在我看来,你知道的类型,它只是你计算它为时已晚。如果你能改变这一点,它会解决你的问题。然后,该方法是这样的:
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 []的常量表达式内部,然后编译它以获取我的字符串参数。
但尽管如此,我也喜欢,如果我能一个对象数组中转发...
为什么你认为你需要的对象存储在一个数组?您能否展示整个表达式的示例,尤其是如何使用数组? – svick 2012-03-11 19:15:35
那么,我想模仿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
所以,我需要评估IN运算符的所有参数,它可以导致简单类型(int,string,decimal),但也可能导致我的模型中的任何类型,或者它们的集合。之后,我将它们转换为左操作数的类型。我不知道,也许我太过于复杂 – 2012-03-11 19:36:50