2012-03-11 77 views
1

我正在做一些解析用戶輸入,在這裏我需要解析應該是某些類型的參數數組。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

回答

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

@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 []的常量表達式內部,然後編譯它以獲取我的字符串參數。

但儘管如此,我也喜歡,如果我能一個對象數組中轉發...

相關問題