Expression Tree Practice: Variables, Constants, and Assignments
Defining Variables
ParameterExpression
is used to create variables and variable parameter expressions.
In C#, variables are divided into the following types:
- Value types
- Reference types
- Pointer types
Generally, only value types and reference types are used; pointer types will not be discussed here.
The basic value types in C# include: bool, byte, char, double, float, int, long, etc. (In C#, arrays belong to reference types).
An expression tree can create a variable in two ways:
ParameterExpression varA = Expression.Variable(typeof(int), "x");
ParameterExpression varB = Expression.Parameter(typeof(int), "y");
The difference:
Expression.Variable()
indicates the creation of a variable;
Expression.Parameter()
indicates the creation of an input parameter;
As for the usage difference, there will be many specific examples later to illustrate.
Commonality: The generated type is ParameterExpression
.
Example:
int a;
ParameterExpression varA = Expression.Variable(typeof(int), "x");
static void Main(string[] args)
{
// Equivalent to int b in Test()
ParameterExpression varB = Expression.Parameter(typeof(int), "y");
Console.ReadKey();
}
public static void Test(int b)
{
Console.WriteLine(b);
}
Reference types are also created using the same method.
The example of methods regarding reference types will be used later.
Defining Constants
Use Expression.Constant()
to define a constant.
Example:
ConstantExpression constant = Expression.Constant(100);
ConstantExpression constant1 = Expression.Constant(100, typeof(int));
It is recommended to use the overload with two parameters, as it makes browsing the code easier and facilitates finding modifications.
Assignment
Expression.Assign()
is used to assign values to variables in the expression tree.
The commonly defined usage is as follows:
BinaryExpression Assign(Expression left, Expression right);
This assigns the value of the right-hand expression to the left-hand expression.
To assign values to variables:
ParameterExpression a = Expression.Variable(typeof(int), "x");
ConstantExpression constant = Expression.Constant(100, typeof(int));
BinaryExpression assign = Expression.Assign(a, constant);
Note on Overloaded Method Types
Common overloaded methods of Console
include:
public static void WriteLine(object value);
public static void WriteLine(float value);
public static void WriteLine(string value);
When using expression trees, be careful to call the overloaded methods; do not be misled by implicit conversions in normal code.
int a = 100;
Console.WriteLine(a);
ParameterExpression aa = Expression.Parameter(typeof(int), "a");
BinaryExpression aaa = Expression.Assign(aa, Expression.Constant(100, typeof(int)));
MethodCallExpression method = Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }), aa);
// If you haven't learned to execute expression trees, you can ignore this part for now
var call = Expression.Block(new ParameterExpression[] { aa }, aaa, method);
Expression<Action> lambda = Expression.Lambda<Action>(call);
lambda.Compile()();
When outputting variable a
, the system performs an implicit type conversion. However, when using expression trees to call methods, the types must correspond to find the correct overloaded method. The expression tree call to Console.WriteLine()
will throw the following error:
System.ArgumentException: "Expression of type 'System.Int32' cannot be used for parameter of type 'System.String' of method 'Void WriteLine(System.String)'
Arg_ParamName_Name"
文章评论