2009-04-15 33 views
5

Tôi muốn biết nếu có thể sử dụng biểu thức dưới dạng biến/tham số trong C#. Tôi muốn làm điều gì đó như thế này:C#: Có cách nào để sử dụng biểu thức dưới dạng biến/tham số không?

int x = 0; 
public void g() 
{ 
    bool greaterThan = f("x>2"); 
    bool lessThan = f("x<2"); 
} 
public bool f(Expression expression) 
{ 
    if(expression) 
     return true; 
    else 
     return false; 
} 

Đây là những gì tôi không muốn làm:

int x = 0; 
public void g() 
{ 
    bool greaterThan = f(x, '<', 2); 
} 

public bool f(int x, char c, int y) 
{ 
    if(c == '<') 
     return x < y; 
    if(c == '>') 
     return x > y; 
} 

Thật gì tôi nhận xét là một cách để có được xung quanh bằng cách sử dụng công tắc hoặc một loạt các câu lệnh if cho mỗi: <> < => = ==! =. Có cách nào để làm điều đó?

Chỉnh sửa: Giả sử biểu thức là một chuỗi, như "x < 2". Có cách nào để đi từ chuỗi đến một vị từ mà không cần sử dụng một loạt các câu lệnh if trong điều kiện?

Trả lời

11

Rất có thể, không đúng cú pháp chính xác của bạn.

int x = 0; 
public void g() 
{ 
    bool greaterThan = f(i => i > 2, x); 
    bool lessThan = f(i => i < 2, x); 
} 
public bool f(Func<int,bool> expression, int value) 
{ 
    return expression(value); 
} 

Thực ra, điều này nên gần hơn với những gì bạn muốn.

int x = 0; 
public void g() 
{ 
    bool greaterThan = f(() => x > 2); 
    bool lessThan = f(() => x < 2); 
} 
public bool f(Func<bool> expression) 
{ 
    return expression(); 
} 

Trả lời vào Edit

Nếu bạn muốn có thể nói f("x < 2"), nó sẽ là gần như không thể. Bỏ qua việc phân tích cú pháp nó (có thể khó chịu), bạn phải nắm bắt giá trị của x, nhưng nó chỉ là một ký tự cho f, điều này làm cho nó không thể thực hiện được.

+0

Tuyệt. Tôi đã chỉnh sửa câu hỏi của mình một chút như sau: Giả sử rằng biểu thức là một chuỗi, như "x <2". Có cách nào để đi từ chuỗi đến một vị từ mà không sử dụng một loạt các câu lệnh if trên ký tự? –

+1

Nếu nó thực sự là một chuỗi, sẽ không có một câu trả lời dễ dàng và nhanh chóng. Nhưng nếu bạn có nghĩa là bạn muốn gõ f (x> 2) ;, sau đó chỉ cần thực hiện f lấy một tham số boolean. – Samuel

+0

Drats, ok. Cảm ơn vì sự trả lời. –

9

Nếu bạn thực sự muốn vượt qua xung quanh mã cho điều này, bạn muốn có một Predicate:

int x = 0; 
public void g() 
{ 
    bool greaterThan = f(i => i>2, x); 
    bool lessThan = f(i => i<2, x); 
} 
public bool f(Predicate<int> expression, int value) 
{ 
    return expression(value); 
} 

Ngược lại, nếu bạn chỉ cần thay thế bool cho Expression trong ví dụ đầu tiên bạn mã của bạn sẽ biên dịch tốt:

int x = 0; 
public void g() 
{ 
    bool greaterThan = f(x>2); 
    bool lessThan = f(x<2); 
} 
public bool f(bool expression) 
{ 
    if(expression) 
     return true; 
    else 
     return false; 
} 
+0

Wow, downvote đó là hoàn toàn uncalled cho. Câu trả lời này là chính xác và phù hợp hơn với những gì người hỏi muốn về cú pháp. – Samuel

+0

Tôi có một trình giữ chỗ chỉ là câu đầu tiên, khiến tôi mất quá nhiều thời gian để lấy nó ra. –

+0

Thực ra, bạn không thể chỉ gọi biểu thức(). Bạn phải vượt qua trong một int. – Samuel

7

Trừ khi tôi là thiếu một cái gì đó ... tại sao bạn không chỉ cần làm:

bool greaterThan = x > 5; 
bool lessThan = x < 5; 
.210

Một so sánh boolean đã là một biểu hiện ...

Edit:

Vì vậy, cho chức năng của bạn, chỉ cần vượt qua một bool: Sửa

public void f(bool expression) 
{ 
    // expression is either true or false... 
} 

f(x<5); // called like this 
+0

Sự khác biệt chính giữa câu trả lời của bạn và các câu trả lời khác trong chuỗi này là _when_ so sánh được thực thi. Mã của bạn chạy ngay lập tức, mã khác chỉ chạy khi 'expression' được gọi. Điều này có thể hữu ích nếu bạn không cần phải biết 'greaterThan' và' x' là tốn kém để tính toán. –

+0

Giả sử 'x' là một cuộc gọi hàm hoặc một biểu thức" trì hoãn "khác. –

+0

Cảm ơn bạn đã làm rõ, tôi không sử dụng .NET 3.0 vì vậy tôi không quen thuộc với các biểu thức lambda như tôi nên là –

0

: Giả sử rằng biểu thức là một chuỗi, như "x < 2". Có cách nào để đi từ chuỗi đến một vị từ mà không cần sử dụng một loạt các câu lệnh if trong điều kiện?

Có một số thủ thuật bạn có thể sử dụng để biến chuỗi thành mã trong .Net: CodeDom, Reflection.Emit, hoặc thậm chí kịch bản trình biên dịch trong trình bao. Tuy nhiên, không có điều nào trong số này đơn giản như một nhanh chóng eval() trong ngôn ngữ kịch bản, và điều này thường được tán thành trong. Net anyway trừ khi bạn thực sự biết những gì bạn đang làm.

Thay vào đó,.Net cung cấp không gian tên System.Addin như một cách an toàn hơn để cho phép tiện ích người dùng mở rộng ứng dụng của bạn.

2

Chỉnh sửa: Giả sử biểu thức là một chuỗi, như "x < 2". Có cách nào để đi từ chuỗi đến một vị từ mà không cần sử dụng một loạt các câu lệnh if trong điều kiện?

Như một số người đã đề cập; nếu bạn muốn có thể sử dụng chuỗi, bạn cần phân tích cú pháp. Bạn không thực sự muốn viết trình phân tích cú pháp C# của bạn, thật may mắn, một số người ở Microsoft đã làm điều đó với Dynamic LINQ.

Dưới đây là một giải pháp cho câu hỏi cụ thể của bạn:

public void g() 
{ 
    int x = 0; 

    bool greaterThan = f("x > 2", x); 
    bool lessThan = f("x < 2", x); 
} 

public bool f(string expression, int x) 
{ 
    ParameterExpression xExpr = Expression.Parameter(typeof(int), "x"); 

    LambdaExpression e = DynamicExpression.ParseLambda(
     new ParameterExpression[] { xExpr }, typeof(bool), expression); 

    return (bool)e.Compile().DynamicInvoke(x); 
} 

Bây giờ, rõ ràng, điều này sẽ thổi lên trên typo nhỏ nhất trong chuỗi. Bạn thực sự cần phải suy nghĩ về việc liệu bạn có thực sự cần điều này không. Nhưng nếu bạn thực sự làm, bạn có thể sử dụng phương thức DynamicExpression.ParseLambda để phân tích chuỗi thành LambdaExpression s.

+0

Tôi thực sự không thực sự cần, nhưng điều đó thật tuyệt vời. Tôi se thử no. –

Các vấn đề liên quan