繁体   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