Get method's parameters names and values from inside method
Is there a way in .NET to know what parameters and their values were passed to a method. Reflection way? This will be used fro开发者_JAVA技巧m inside the method. It has to be generic so it can be used from any method. This is for logging purposes.
Call MethodBase.GetCurrentMethod().GetParameters()
.
However, it is not possible to get the parameter values; due to JIT optimization, they might not even exist anymore.
MethodInfo.GetCurrentMethod()
will give you information about the current method and then get information about the parameters using GetParameters()
.
What you're trying to do can be achieved easily using aspect oriented programming. There are good tutorials online, I'll point to two of them:
- http://ayende.com/Blog/archive/2008/07/31/Logging--the-AOP-way.aspx
- http://www.codeproject.com/KB/cs/UsingAOPInCSharp.aspx
public void FunctionWithParameters(string message, string operationName = null, string subscriptionId = null)
{
var parameters = System.Reflection.MethodBase.GetCurrentMethod().GetParameters();
this.PrintParams(parameters, message, operationName, subscriptionId);
}
public void PrintParams(ParameterInfo[] paramNames, params object[] args)
{
for (int i = 0; i < args.Length; i++)
{
Console.WriteLine($"{paramNames[i].Name} : {args[i]}");
}
}
You need AOP to achieve what you are looking for. in c# you can use DispatchProxy to do that. Check the following How to wrap existing object instance into DispatchProxy?
Nowadays a feature that could be used to achieve this is Roslyn's Source Generators.
In this way, the code that gets the parameters' values would be generated at compile-time based on the method definition. Could be interpreted as “compile-time reflection”.
Let's show an example to try to explain it better:
public void MethodInspectingItsOwnParameters(
[Description("First parameter")]
string paramName_1,
[Description("Second parameter")]
int paramName_2,
// ...
[Description("N-th parameter")]
object paramName_N,
// ...
[Description("Last parameter")]
bool paramName_M)
{
var paramsAndValues = new List<KeyValuePair<string, object>>();
// -
// => Put here the code that, using Roslyn's compile time
// metaprogramming, inspect the parameters from the method
// definition and at compile time generate the code that
// at run time will get the parameters's values and load
// them into [paramsAndValues]
// -
// #Rosalyn generated code
// · Code autogenerated at compile time
// => loads parameter's values into [paramsAndValues]
// -
// Eg (Hypothetical example of the code generated at compile
// time by Roslyn's metaprogramming):
//
// paramsAndValues.Add("paramName_0", paramName_1);
// ...
// paramsAndValues.Add("paramName_N", paramName_N);
// ...
// paramsAndValues.Add("paramName_M", paramName_M);
//
// - Note: this code will be regenerated with each compilation,
// so there no make sense to do nameof(paramName_N)
// to obtaint parameter's name
// #End Rosalyn generated code
foreach (var param in paramsAndValues)
{
string paramName = param.Key;
object paramValue = param.Value;
// In this section of the normal code (not generated at
// compile time) do what you require with the
// parameters/values already loaded into [paramsAndValues]
// by the compile time generated code
}
}
精彩评论