C# 获取方法';方法内部的参数名称和值

C# 获取方法';方法内部的参数名称和值,c#,.net,C#,.net,在.NET中是否有一种方法可以知道哪些参数及其值被传递给了一个方法。反思方式?这将从方法内部使用。它必须是泛型的,以便可以从任何方法中使用。这是为了记录日志。使用面向方面的编程可以很容易地实现您想要做的事情。网上有很好的教程,我将指出其中两个: 调用MethodBase.GetCurrentMethod().GetParameters() 但是,无法获得参数值;由于JIT优化,它们可能不再存在。将为您提供有关当前方法的信息,然后使用获取有关参数的信息。您需要AOP来实现所需的目标。 在c#

在.NET中是否有一种方法可以知道哪些参数及其值被传递给了一个方法。反思方式?这将从方法内部使用。它必须是泛型的,以便可以从任何方法中使用。这是为了记录日志。

使用面向方面的编程可以很容易地实现您想要做的事情。网上有很好的教程,我将指出其中两个:


调用
MethodBase.GetCurrentMethod().GetParameters()


但是,无法获得参数值;由于JIT优化,它们可能不再存在。

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

您需要AOP来实现所需的目标。 在c#中,您可以使用DispatchProxy来实现这一点。
检查以下内容

现在,可用于实现此目的的功能是

这样,获取参数值的代码将在编译时基于方法定义生成。可以解释为“编译时反射”

让我们举一个例子来更好地解释它:

public void方法检查自身参数(
[说明(“第一个参数”)]
字符串paramName_1,
[说明(“第二个参数”)]
int paramName_2,
// ...
[说明(“第N个参数”)]
对象参数名,
// ...
[说明(“最后一个参数”)]
布尔参数名称(M)
{
var paramsAndValues=新列表();
//  -
//=>将代码放在这里,使用Roslyn的编译时
//元编程,检查方法中的参数
//定义并在编译时生成
//在运行时,将获取参数的值和负载
//将它们转换为[参数和值]
//  -
//#Rosalyn生成的代码
//·编译时自动生成的代码
//=>将参数的值加载到[paramsAndValues]中
// -
//例如(编译时生成的代码的假设示例)
//时间由Roslyn的元编程确定):
//
//paramsAndValues.Add(“paramName_0”,paramName_1);
//      ...
//paramsAndValues.Add(“paramName”,paramName);
//      ...
//paramsAndValues.Add(“paramName_M”,paramName_M);
//
//-注:此代码将在每次编译时重新生成,
//因此,使用nameof(paramName_N)是没有意义的
//获取参数名称的步骤
//#结束Rosalyn生成的代码
foreach(paramsAndValues中的var param)
{
字符串paramName=param.Key;
对象参数值=参数值;
//本节中的正常代码(未在
//编译时)使用
//已加载到[paramsAndValues]中的参数/值
//通过编译时生成的代码
}
}
public void FunctionWithParameters(字符串消息,字符串操作名称=null,字符串订阅ID=null)
{
var parameters=System.Reflection.MethodBase.GetCurrentMethod().GetParameters();
this.PrintParams(参数、消息、操作名、订阅ID);
}
public void PrintParams(参数信息[]参数名称,参数对象[]参数)
{
for(int i=0;i

+1 AFAIK这是实现这一目标的唯一有效途径。唯一的另一种方法是使用另一个进程来调试当前进程,这个进程令人讨厌、不可靠而且速度慢。为什么要投否决票?面向方面编程是一种方法论。它最终还是转换成了一些.NET api。这并没有给出参数值。我在这一点上做了这个,我从来没有玩过Roslyn的源代码生成器。这个问题将是一个很好的学习练习。如果我花点时间,我会回来给这个答案添加一些(希望是)工作代码。
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]}");
    }
}