簡體   English   中英

從方法內部獲取方法的參數名稱和值

[英]Get method's parameters names and values from inside method

.NET 中有沒有辦法知道哪些參數及其值被傳遞給了一個方法。 反射方式? 這將從方法內部使用。 它必須是通用的,以便可以從任何方法中使用。 這是用於記錄目的。

MethodInfo.GetCurrentMethod()將為您提供有關當前方法的信息,然后使用GetParameters()獲取有關參數的信息。

調用MethodBase.GetCurrentMethod().GetParameters()
但是,無法獲取參數值; 由於 JIT 優化,它們甚至可能不再存在。

使用面向方面的編程可以輕松實現您想要做的事情。 網上有很好的教程,我將指出其中兩個:

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]}");
    }
}

在此處輸入圖片說明

你需要 AOP 來實現你想要的。 在 c# 中,您可以使用 DispatchProxy 來做到這一點。 檢查以下如何將現有對象實例包裝到 DispatchProxy 中?

如今,可用於實現此目的的功能是Roslyn 的 Source Generators

這樣,獲取參數值的代碼將在編譯時根據方法定義生成。 可以解釋為“編譯時反射”。

讓我們舉一個例子來嘗試更好地解釋它:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM