1

我正在对用户输入进行一些解析,在这里我需要解析应该是特定类型的参数数组。

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

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)));

到目前为止一切顺利:我得到了数组中各种类型的对象列表。

但是,当我最终获得所需的类型时,我尝试将所有值从上部数组转换为该类型(假设该类型通常是 int)我将其转换:

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

当 expr 实际上是字符串“aaaaa”时,这是两个命令的调试视图:

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

现在,这是我的问题:这不会引发异常。但它会在最终编译表达式时。我的意思是,字符串不是整数。

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

有办法治愈吗?

编辑:代码如下所示:

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);
}
4

2 回答 2

2

在我看来,您知道类型,只是您计算得太晚了。如果你能改变它,它会解决你的问题。该方法将如下所示:

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);
于 2012-03-11T21:12:49.903 回答
1

@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;
    }

我将我的参数转发到我可以在 string[] 的常量表达式中实际引用左操作数类型的地步,然后编译它以获取我的字符串参数。

但是,如果我可以在对象数组中转发它,我会很高兴......

于 2012-03-12T10:47:34.300 回答