Information Technology Reference
In-Depth Information
var
allParameters =
from
element
in
exp.Arguments
select
processArgument(element);
Console
.WriteLine(
"Calling {0}"
, methodName);
foreach
(
var
parm
in
allParameters)
Console
.WriteLine(
"\tParameter type = {0}, Value = {1}"
,
parm.Item1, parm.Item2);
return default
(TResult);
}
private
Tuple
<
Type
,
object
> processArgument(
Expression
element)
{
object
argument =
default
(
object
);
LambdaExpression
l =
Expression
.Lambda(
Expression
.Convert(element, element.Type));
Type
parmType = l.ReturnType;
argument = l.Compile().DynamicInvoke();
return
Tuple
.Create(parmType, argument);
}
Starting from the beginning of CallInterface, the first thing this code does
is look at the body of the expression tree. That's the part on the right side
of the lambda operator. Look back at the example where I used
CallInterface(). That example called it with srver.DoWork(172). It is a
MethodCallExpression, and that MethodCallExpression contains all the
information you need to understand all the parameters and the method
name invoked. The method name is pretty simple: It's stored in the Name
property of the Method property. In this example, that would be
'DoWork'. The LINQ query processes any and all parameters to this
method. The interesting work in is processArgument.
processArgument evaluates each parameter expression. In the example
above, there is only one argument, and it happens to be a constant, the
value 172. However, that's not very robust, so this code takes a different
strategy. It's not robust, because any of the parameters could be method
calls, property or indexer accessors, or even field accessors. Any of the
method calls could also contain parameters of any of those types. Instead of
trying to parse everything, this method does that hard work by leveraging