簡體   English   中英

從調用方法中的變量獲取名稱-創建調用方法簽名,參數和值

[英]Get name from variable in calling method - creating calling method signature, parameters and values

我正在尋找一種方法來掌握傳遞到擴展方法中的變量的名稱。 我想在調用變量中包含參數的名稱。 聽起來很奇怪,讓我解釋一下。

假設這段測試代碼

    private static void TestingMethod(string firstParam, int secondParam, bool thirdParam)
    {
        try
        {
            throw new InvalidOperationException("This named optional params stuff, it's just not working boss");
        }
        catch (Exception ex)
        {
            GenericLog_Exception(ex, "it's on fire, please help");
        }
    }

在最后一行,您可以看到正在記錄的異常。 我希望能夠提供可選的參數支持。 因此,開發人員可以在需要時添加參數信息。

我已經在stackoverflow上看到了很多關於此的帖子,有很多不同的方法。 最主要的是 它不能完全通用地完成。

一些代碼說明:

    static string GetCallingMethodSignature()
    {
        StackTrace stackTrace = new StackTrace();

        // Get calling method name
        var callingMethod = stackTrace.GetFrame(1).GetMethod();
        var callingMethod_Name = callingMethod.Name;

        // get calling method params
        string retVal = string.Empty;

        var callingMethod_Parameters = callingMethod.GetParameters();

        retVal = callingMethod_Name + "(";
        foreach (var param in callingMethod_Parameters)
        {
            retVal += param.Name + ": " + param.ToString() + ",";
        }
        retVal.Remove(retVal.Length - 1, 1);
        retVal += ")";

        return retVal;
    }

現在,此測試代碼正在獲取調用方法的名稱及其參數。 即,參數的名稱。 但不是他們的價值觀。 param.tostring()部分僅返回類型名稱。 沒有價值。 我一直在閱讀,看來這不可能通過反思來完成。

因此,然后我嘗試了另一種方法,為什么不提供開發人員認為適合記錄的參數。 無論如何,您大部分時間都不需要它們。

private static string GenericLog_Exception(Exception exceptionData, string extraInformation, params KeyValuePair<string, object>[] parameters)

因此,這是一種新的測試方法,我將選擇的參數提供給異常日志記錄方法。 但是,如果您想使此工作正常進行,那么每次進行此調用都是一件難事。

    private static void TestingMethod(string firstParam, int secondParam, bool thirdParam)
    {
        try
        {
            throw new InvalidOperationException("This named optional params stuff, it's just not working boss");
        }
        catch (Exception ex)
        {
            GenericLog_Exception(ex, "it's on fire, please help", new KeyValuePair<string, object>[]{
                new KeyValuePair<string, object>("firstParam", firstParam),
                new KeyValuePair<string, object>("secondParam", secondParam),
                new KeyValuePair<string, object>("thirdParam", thirdParam)
            });
        }
    }

現在這正在工作。 但是正如我所說,我發現底部很麻煩。 我一直在考慮一種擴展方法,因此可以縮短每個kvp的創建時間。

internal static class ExtensionMethodsForTesting
{
    internal static KeyValuePair<string, object> AsKeyValuePair(this string parameter)
    {
        var name = nameof(parameter);
        return new KeyValuePair<string, object>(name, parameter);
    }
}

然后將其用作

GenericLog_Exception(ex, "it's on fire, please help", new KeyValuePair<string, object>[] { firstParam.AsKeyValuePair() });

這使我面臨與以前相同的問題。 當然,nameof(parameter)返回“ parameter”。 對於每種類型,我還必須制作幾個擴展方法。 或檢查擴展方法中的類型,以確保獲得正確的值。

因此,簡而言之:如何獲得調用擴展方法的變量的名稱?

您可以執行以下“ hack”。 將方法的簽名更改為以下內容:

private static string GenericLog_Exception(
        Exception exceptionData, 
        string extraInformation, 
        params Expression<Func<object>>[] parameters)

現在,您的呼叫站點看上去會更加干凈:

GenericLog_Exception(ex, 
                     "it's on fire, please help",
                     () => firstParam,
                     () => secondParam,
                     () => thirdParam);

您可以通過以下方式從表達式中提取參數信息(為方便起見,使用C#元組支持):

private static (object Value, string ParamName) GetParameterInfo
    (Expression<Func<object>> expr)
{
    //First try to get a member expression directly.
    //If it fails we know there is a type conversion: parameter is not an object 
    //(or we have an invalid lambda that will make us crash)
    //Get the "to object" conversion unary expression operand and then 
    //get the member expression of that and we're set.
    var m = (expr.Body as MemberExpression) ??
            (expr.Body as UnaryExpression).Operand as MemberExpression;

    return (expr.Compile().Invoke(), m.Member.Name);
}

暫無
暫無

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

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