Tôi đang thực hiện Func ->Biểu thức ->Func chuyển đổi. Nó hoạt động tốt nếu tôi tạo Func <>() từ phương thức (ví dụ đầu tiên dưới đây) tuy nhiên nếu tôi tạo hàm bằng cách sử dụng cây biểu thức (ví dụ thứ 2), nó không thành công với NullReferenceException khi truy cập func2.Method.DeclaringType. Tên đầy đủ. Và điều này là do DeclaringType is null. (NJection sử dụng sự phản chiếu vì vậy tôi nghĩ đó là lý do tại sao nó cần DeclaringType.)Có cách nào để đặt 'DeclaringType' trong cây biểu thức không?
Làm thế nào tôi có thể điền vào loại DeclaringType cho Func <> được tạo ra bằng cách biên dịch một cây biểu hiện? (có lẽ nó không thể?) DeclaringType được thiết lập trong ví dụ đầu tiên.
Sử dụng một Func <> từ một phương pháp ... (hoạt động tốt)
// Build a Func<>
Func<int, int> add = Add;
// Convert it to an Expression using NJection Library
Expression<Func<int, int>> expr = ToExpr<Func<int, int>>(add);
// Convert it back to a Func<>
Func < int, int> func = expr.Compile();
// Run the Func<>
int result = func(100);
Sử dụng một cây biểu thức (không hoạt động) ...
// Build a Func<> using an Expression Tree
ParameterExpression numParam = Expression.Parameter(typeof(int));
ConstantExpression five = Expression.Constant(5, typeof(int));
BinaryExpression numAddFive = Expression.Add(numParam, five);
Func<int, int> func2 =
Expression.Lambda<Func<int, int>>(
numAddFive,
new ParameterExpression[] { numParam }).Compile();
// Convert to an Expression using NJection (EXCEPTION ON NEXT LINE)
// ToExpr is trying to access func2.Method.DeclaringType.FullName(DeclaringType is null)
Expression<Func<int, int>> exp2 = ToExpr<Func<int, int>>(func2);
// Convert it back to a Func<>
Func<int, int> func2b = exp2.Compile();
// Run the Func<>
int result2 = func2b(100);
Bạn đang cố gắng đạt được điều gì với 'ToExpr> (func2)'? Bạn muốn quay trở lại loại biểu hiện nào? –
torvin
Tôi vẫn đang học LINQ/labda/etc. Mục tiêu của tôi là đơn giản hóa một chương trình biểu thức biểu thức (hoặc cây). Có lẽ tôi có thể có trình biên dịch biên dịch một biểu thức để mã sau đó lấy mã đó và chuyển nó trở lại một cây biểu thức. Tôi đoán cây biểu thức kết quả sẽ là một phiên bản rút gọn của bản gốc. Vì vậy, nếu tôi có một cây biểu thức của một + a + a + 2 + 4 + 3 thì tôi biên dịch nó và chuyển đổi mã đó trở lại thành một biểu thức tôi sẽ nhận được (3 * a) +9. (Tôi đoán) Tôi đã nói Func -> Expr -> Fun nhưng mục tiêu thực sự là Expr -> Func (code) -> Expr. Nếu tôi có thể làm việc đầu tiên thì tôi nghĩ tôi có thể làm sau. – Sunsetquest
Tại sao bạn muốn đơn giản hóa biểu thức? Nếu bạn chỉ cần biên dịch và chạy sau đó, trình biên dịch vẫn sẽ làm tất cả các tối ưu hóa cho nó, vì vậy đừng bận tâm. Nếu bạn đang cố gắng sử dụng trình biên dịch để đơn giản hóa các biểu thức cho bạn cho một số nhiệm vụ khác - bạn có thể sẽ không đạt được nhiều, vì ý tưởng của bạn về 'đơn giản' có thể khá khác với trình biên dịch. – torvin