Tony_Henrich
Tony_Henrich

Reputation: 44085

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 from inside the method. It has to be generic so it can be used from any method. This is for logging purposes.

Upvotes: 25

Views: 29485

Answers (7)

Albertote
Albertote

Reputation: 21

I had the same issue and here goes my solution for logging all the parameters and their values. ONLY wihtin a Controller Context:

    public static string CallParams = "";
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
         base.OnActionExecuting(filterContext);                    
         CallParams = JsonConvert.SerializeObject(filterContext.ActionParameters);
    }

Hope it helps

Upvotes: 0

Natalie Polishuk
Natalie Polishuk

Reputation: 193

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

Upvotes: 5

CicheR
CicheR

Reputation: 399

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
    }
}

Upvotes: 0

Waleed A.K.
Waleed A.K.

Reputation: 1656

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?

Upvotes: 0

Darin Dimitrov
Darin Dimitrov

Reputation: 1038720

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

Upvotes: 7

SLaks
SLaks

Reputation: 887285

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

Upvotes: 11

sukru
sukru

Reputation: 2259

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:

Upvotes: 6

Related Questions