我可以从当前执行的函数中以程序方式获取参数名称/值吗?

Mar*_*ter 40 .net c# reflection parameters logging

我想做这样的事情:

public MyFunction(int integerParameter, string stringParameter){
    //Do this:
    LogParameters();
    //Instead of this:
    //Log.Debug("integerParameter: " + integerParameter + 
    //          ", stringParameter: " + stringParameter);

}

public LogParameters(){
    //Look up 1 level in the call stack (if possible),
    //Programmatically loop through the function's parameters/values
    //and log them to a file (with the function name as well).
    //If I can pass a MethodInfo instead of analyzing the call stack, great.
}
Run Code Online (Sandbox Code Playgroud)

我甚至不确定我想要做什么是可能的,但能够在运行时自动将参数名称/值输出到文件而不显式编写代码来记录它们将是非常好的.

可能吗?

Mar*_*ter 22

我意识到人们与提到PostSharp的其他问题相关联,但我无法发布解决我的问题的代码(使用PostSharp),以便其他人可以从中受益.

class Program {
    static void Main(string[] args) {
        Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
        new MyClass().MyMethod(44, "asdf qwer 1234", 3.14f, true);
        Console.ReadKey();
    }
}
public class MyClass {
    public MyClass() {
    }
    [Trace("Debug")]
    public int MyMethod(int x, string someString, float anotherFloat, bool theBool) {
        return x + 1;
    }
}
[Serializable]
public sealed class TraceAttribute : OnMethodBoundaryAspect {
    private readonly string category;

    public TraceAttribute(string category) {
        this.category = category;
    }

    public string Category { get { return category; } }

    public override void OnEntry(MethodExecutionArgs args) {
        Trace.WriteLine(string.Format("Entering {0}.{1}.", 
                                      args.Method.DeclaringType.Name, 
                                      args.Method.Name), category);

        for (int x = 0; x < args.Arguments.Count; x++) {
            Trace.WriteLine(args.Method.GetParameters()[x].Name + " = " + 
                            args.Arguments.GetArgument(x));
        }
    }

    public override void OnExit(MethodExecutionArgs args) {
        Trace.WriteLine("Return Value: " + args.ReturnValue);

        Trace.WriteLine(string.Format("Leaving {0}.{1}.", 
                                      args.Method.DeclaringType.Name, 
                                      args.Method.Name), category);
    }
} 
Run Code Online (Sandbox Code Playgroud)

简单地将Trace属性添加到方法将导致输出非常好的调试信息,如下所示:

Debug: Entering MyClass.MyMethod. 
x = 44
someString = asdf qwer 1234
anotherFloat = 3.14
theBool = True
Return Value: 45
Debug: Leaving MyClass.MyMethod.
Run Code Online (Sandbox Code Playgroud)

  • 这是可能的postharp的快递版本(这是免费的)? (3认同)

Ben*_*igt 12

从理论上讲,关闭调试构建和优化是可能的,但实际上,我建议你想要一些源代码重写传递.

人们会不断地告诉你反射会不会有效,所以这里的函数实际上能够获得参数值.这是不太可能在启用优化的可靠地工作(例如,有可能甚至堆栈帧时,内联是),并得到安装调试,以便您可以调用该函数几乎不会那么简单,你希望.


Tay*_*ese 7

StackTrace stackTrace = new StackTrace();
ParameterInfo[] parameters = stackTrace.GetFrame(1).GetMethod().GetParameters();
Run Code Online (Sandbox Code Playgroud)

注意,GetFrame(1)获取调用方法而不是当前方法.这应该可以为您提供所需的结果,并允许您在LogParameters()中执行以下代码.

您需要调用LogParameters,因为您无法从ParameterInfo获取integerParameter和stringParameter的反射值.

LogParameters(integerParameter, stringParameter);
Run Code Online (Sandbox Code Playgroud)