In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-12 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces the relevant knowledge of how to create the expression tree of C# value type, reference type, generics, collection, the content is detailed and easy to understand, the operation is simple and fast, and has a certain reference value. I believe you will gain something after reading this article on how to create the expression tree of C# value types, reference types, generics, collections. Let's take a look.
First, define variables
In the C # expression tree, define a variable, using ParameterExpression.
There are two ways to create variable nodes
Expression.Parameter () Expression.Variable () / in addition, you can use Expression.Constant () to define a constant.
Both methods generate the ParameterExpression types Parameter () and Variable () both have two overloads. They create a ParameterExpression node that can be used to identify parameters or variables in the expression tree.
For using definitions:
Expression.Variable is used to declare local variables within a block.
Expression.Parameter is used to declare the parameters of the input value.
Let's look at the first one first.
Public static ParameterExpression Parameter (Type type) {return Parameter (type, name: null);} public static ParameterExpression Variable (Type type) {return Variable (type, name: null);}
From the perspective of the code, there is no difference.
And look at the overload with two parameters.
Public static ParameterExpression Parameter (Type type, string name) {Validate (type, allowByRef: true); bool byref = type.IsByRef; if (byref) {type = type.GetElementType ();} return ParameterExpression.Make (type, name, byref) } public static ParameterExpression Variable (Type type, string name) {Validate (type, allowByRef: false); return ParameterExpression.Make (type, name, isByRef: false);}
As you can see, there is only one allowByRef difference between the two. Paramter allows Ref and Variable does not.
The author did not find a specific difference between the official documentation and other author articles. After searching for stackoverflow and looking at the source code, I determined that the difference between them was that Variable could not use the ref type.
Literally, to declare a variable, you should use Expression.Variable, and the arguments passed in to the function should use Expression.Parameter.
Both value types and reference types are defined in this way.
Second, access the property fields and methods of variables / types
Access the properties of a variable or type, using the
Expression.Property ()
Access properties or fields of a variable / type, using the
Expression.PropertyOrField ()
A method to access a variable or type, using the
Expression.Call ()
Access property fields and methods
Expression.MakeMemberAccess
They all return a MemberExpression type.
In use, there is a small difference between instantiated / uninstantiated, which says variables or types.
It means that a value type that has been defined or an instantiated reference type is a variable
Type, which refers to a reference type, does not require instantiated static types or static property fields / methods.
The above explanation is not very rigorous, and the following example will explain it slowly.
1. Access Properti
Invoke the property using Expression.Property () or Expression.PropertyOrField ().
Call static type properties
Console is a static type, and Console.Title can get the actual location of the compiler program.
Console.WriteLine (Console.Title)
Use the expression tree to express as follows
MemberExpression member = Expression.Property (null, typeof (Console) .GetProperty ("Title"); Expression lambda = Expression.Lambda (member); string result = lambda.Compile () (); Console.WriteLine (result); Console.ReadKey ()
Because you are calling a statically typed property, the first parameter is empty.
The second parameter is a PropertyInfo type.
Call instance properties / fields
The C # code is as follows
List a = new List () {1,2,3}; int result = a.count; Console.WriteLine (result); Console.ReadKey ()
In the expression tree, call the properties of the instance
ParameterExpression a = Expression.Parameter (typeof (List), "a"); MemberExpression member = Expression.Property (a, "Count"); Expression lambda = Expression.Lambda (member, a); int result = lambda.Compile () (new List {1,2,3}); Console.WriteLine (result); Console.ReadKey ()
In addition to Expression.Property (), please test the other methods yourself, and I won't repeat them here.
two。 Call function
Use Expression.Call () to call a statically typed function or an instance of a function.
Call a statically typed function
Take Console as an example, call the WriteLine () method
Console.WriteLine ("call WriteLine method"); MethodCallExpression method = Expression.Call (null, typeof (Console) .GetMethod ("WriteLine", new Type [] {typeof (string)}), Expression.Constant ("call WriteLine method"); Expression lambda = Expression.Lambda (method); lambda.Compile () () Console.ReadKey ()
There are many overloading methods for Expression.Call (), and the commonly used overloading method is
Public static MethodCallExpression Call (Expression instance, MethodInfo method, params Expression [] arguments)
Because you are calling a statically typed function, the first instance is empty (instance means instance).
The second method is the overloaded method to call.
The last arguments is the parameter passed in.
Call the function of the instance
Write a class
Public class Test {public void Print (string info) {Console.WriteLine (info);}}
Call the Printf () method of the instance
Test test = new Test (); test.Print ("print out"); Console.ReadKey ()
The expression is as follows
ParameterExpression a = Expression.Variable (typeof (Test), "test"); MethodCallExpression method = Expression.Call (a, typeof (Test) .GetMethod ("Print", new Type [] {typeof (string)}), Expression.Constant ("print out")); Expression lambda = Expression.Lambda (method,a) Lambda.Compile () (new Test ()); Console.ReadKey ()
Note that Expression.Variable (typeof (Test), "test"); has only one variable defined and has not been initialized / assigned yet. For reference types, you need to instantiate.
The above method is passed in through external instantiation, which will be described later on how to instantiate within the expression.
Third, instantiate the reference type
Instantiate the reference type, use new, and then choose to call the appropriate constructor to set the value of the property.
So, according to the above steps, let's discuss it separately.
New
Use Expression.New () to call a type's constructor.
He has five overloads and two commonly used overloads:
Public static NewExpression New (ConstructorInfo constructor); public static NewExpression New (Type type)
Still use the above Test type
NewExpression newA = Expression.New (typeof (Test))
A constructor with no arguments by default, or only one constructor, called as above.
If you specify a constructor like this, you can
NewExpression newA = Expression.New (typeof (Test) .GetConstructor (xxxxxx))
I won't go into details here.
Assign a value to an attribute
You can assign a value to an attribute while instantiating a constructor.
Public static MemberInitExpression MemberInit (NewExpression newExpression, IEnumerable bindings); public static MemberInitExpression MemberInit (NewExpression newExpression, params MemberBinding [] bindings)
The two overloads are the same.
We change the Test class to
Public class Test {public int sample {get; set;} public void Print (string info) {Console.WriteLine (info);}}
And then
Var binding = Expression.Bind (typeof (Test) .GetMember ("sample") [0], Expression.Constant (10); create reference type Expression.MemberInit ()
Represents one or more members that call the constructor and initialize the new object.
If you instantiate a class, you can use the
NewExpression newA = Expression.New (typeof (Test)); MemberInitExpression test = Expression.MemberInit (newA, new List () {})
If you want to assign a value to a member when instantiating
NewExpression newA = Expression.New (typeof (Test)); / / assign a member of type Test var binding = Expression.Bind (typeof (Test) .GetMember ("sample") [0], Expression.Constant (10)); MemberInitExpression test = Expression.MemberInit (newA, new List () {binding}); example
Instantiate a type, call the constructor and assign a value to the member. The sample code is as follows
/ / call the constructor NewExpression newA = Expression.New (typeof (Test)); / / assign a member of type Test var binding = Expression.Bind (typeof (Test) .GetMember ("sample") [0], Expression.Constant (10)) / / instantiate a type MemberInitExpression test = Expression.MemberInit (newA, new List () {binding}) / / call method MethodCallExpression method1 = Expression.Call (test, typeof (Test) .GetMethod ("Print", new Type [] {typeof (string)}), Expression.Constant ("print")); / / call attribute MemberExpression method2 = Expression.Property (test, "sample") Expression lambda1 = Expression.Lambda (method1); lambda1.Compile () (); Expression lambda2 = Expression.Lambda (method2); int sample = lambda2.Compile () (); Console.WriteLine (sample); Console.ReadKey (); IV, instantiate the generic type in the call
Change the Test class to look like this
Public class Test {public void Print (T info) {Console.WriteLine (info);}}
The Test class is already a generic class, expression instantiation example
Static void Main (string [] args) {RunExpression (); Console.ReadKey ();} public static void RunExpression () {/ / call constructor NewExpression newA = Expression.New (typeof (Test)) / / instantiate a type MemberInitExpression test = Expression.MemberInit (newA, new List () {}) / / call method MethodCallExpression method = Expression.Call (test, typeof (Test) .GetMethod ("Print") .MakeGenericMethod (new Type [] {typeof (T)}), Expression.Constant ("print out"); Expression lambda1 = Expression.Lambda (method); lambda1.Compile () () Console.ReadKey ();} 5, define collection variables, initialize, and add elements
Collection types are represented by ListInitExpression.
To create a collection type, you need to use
ElementInit represents the initializer for a single element of the IEnumerable collection.
ListInit initializes a collection.
In C #, collections implement IEnumerable, and collections all have Add collect methods or properties.
To initialize a collection and add elements using C #, you can do this
List list = new List () {"a", "b"}; list.Add
In the expression tree, the element is initialized / added by calling the Add method through ElementInit.
Example
MethodInfo listAdd = typeof (List) .GetMethod ("Add"); / * * new List () * {* "a", * "b" *} * / ElementInit add1 = Expression.ElementInit (listAdd, Expression.Constant ("a"), Expression.Constant ("b"); / / Add ("666") ElementInit add2 = Expression.ElementInit (listAdd, Expression.Constant ("666"))
Example
MethodInfo listAdd = typeof (List) .GetMethod ("Add"); ElementInit add1 = Expression.ElementInit (listAdd, Expression.Constant ("a")); ElementInit add2 = Expression.ElementInit (listAdd, Expression.Constant ("b")); ElementInit add3 = Expression.ElementInit (listAdd, Expression.Constant ("666")); NewExpression list = Expression.New (typeof (List)) / / initialization value ListInitExpression setList = Expression.ListInit (list, add1, add2, add3); / / nothing to execute, just take a look at the output information Console.WriteLine (setList.ToString ()) MemberExpression member = Expression.Property (setList, "Count"); Expression lambda = Expression.Lambda (member); int result = lambda.Compile () (); Console.WriteLine (result); Console.ReadKey (); this is the end of the article on "how to create expression trees for C # value types, reference types, generics, collections". Thank you for reading! I believe you all have a certain understanding of "C # value types, reference types, generics, how to create the expression tree of a collection". If you want to learn more, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.