How to get the value of a reference type in an expression?

I have this method:

public void DoSomething<T>(Expression<Func<T, object>> method) { } 

If this method is called as follows:

 DoSomething(c => c.SomeMethod(new TestObject())); 

... how to get the value of the parameter that was passed to SomeMethod ()?

If the parameter is a value type, this works:

 var methodCall = (MethodCallExpression)method.Body; var parameterValue = ((ConstantExpression)methodCall.Arguments[0]).Value; 

However, when I pass the reference type, the Call.Arguments [0] method is MemberExpression, and I cannot figure out how to write code to get the value from it.

+4
source share
4 answers

Here is the answer (inspired by Akash's answer):

 LambdaExpression lambda = Expression.Lambda(methodCall.Arguments[0]); var compiledExpression = lambda.Compile(); return compiledExpression.DynamicInvoke(); 
+5
source

You will have to evaluate the member expression manually, MemberExpression contains "Expression", which is the container object of the specified member, for this you can create Lamda of your argument, compile and execute it.

 LamdaExpression l = Expression.Lambda(methodCall.Arguments[0]); var c = l.Compile(); var v = c.Invoke(); 

Therefore, no matter what you skip, you will get this in the variable "v".

+3
source

This is not a matter of value type or reference type - it is a matter of constant expression or non-constant expression. I am sure your existing code will not work if you called

 DoSomething(c => c.SomeMethod(DateTime.Now)); 

.

Basically, a method argument is just an expression. This is not the meaning. You could compile this expression and then execute it to get the value at that point in time, but it’s important to understand that the expression itself is not a value. In the case of a constant expression, this is easy, but taking the example DateTime.Now , by definition, the estimated value of the expression changes over time :)

What are you trying to do with an argument? What is the big picture here?

+1
source

First of all, what John said.

There are no values ​​to get ahold, all these are just expressions. What might be of interest is NewExpression , which has the Constructor property; this property contains a mirrored constructor that will be called if you compiled the expression and ran the resulting delegate. You can manually call this constructor and get an instance of what the user intended when creating the instance.

0
source

Source: https://habr.com/ru/post/1304932/


All Articles