简体   繁体   中英

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.

MethodInfo.GetCurrentMethod()将为您提供有关当前方法的信息,然后使用GetParameters()获取有关参数的信息。

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

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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM