22

Is there a way in .NET to know what parameters and their values were passed to a method. Reflection way? This will be used from inside the method. It has to be generic so it can be used from any method. This is for logging purposes.

Cœur
  • 34,719
  • 24
  • 185
  • 251
Tony_Henrich
  • 39,788
  • 66
  • 221
  • 365
  • I ended up making this [User Activity Logging, Telemetry and Variables in Global Exception Handlers project](https://stackoverflow.com/questions/30326673/user-activity-logging-telemetry-and-variables-in-global-exception-handlers) – Jeremy Thompson Jul 10 '17 at 01:27

6 Answers6

10

Call MethodBase.GetCurrentMethod().GetParameters().
However, it is not possible to get the parameter values; due to JIT optimization, they might not even exist anymore.

SLaks
  • 837,282
  • 173
  • 1,862
  • 1,933
9

MethodInfo.GetCurrentMethod() will give you information about the current method and then get information about the parameters using GetParameters().

Darin Dimitrov
  • 994,864
  • 265
  • 3,241
  • 2,902
6

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:

sukru
  • 2,229
  • 14
  • 15
4
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]}");
    }
}

enter image description here

  • not bad but you need to remember to pass in all the parameter's values or the log will end up being innacurate. – Andrew May 30 '22 at 18:15
0

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?

Waleed A.K.
  • 1,470
  • 13
  • 13
0

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
    }
}
CicheR
  • 319
  • 1
  • 11
  • At this point, I have never *played* with Roslyn's Source Generators. This question would be a nice learning exercise to do. If I take the time, I'll come back here to add some (hopefully) working code to this answer. – CicheR Aug 06 '20 at 05:08