Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I get parameter names/values procedurally from the currently executing function?

I would like to do something like this:

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

I'm not even sure what I want to do is possible, but it would be very nice to be able to automatically output parameter names/values at runtime to a file without explicitly writing the code to log them.

Is it possible?

like image 715
Mark Carpenter Avatar asked Mar 08 '10 22:03

Mark Carpenter


People also ask

How get arguments name in Python?

To extract the number and names of the arguments from a function or function[something] to return ("arg1", "arg2"), we use the inspect module. The given code is written as follows using inspect module to find the parameters inside the functions aMethod and foo.

Which of the following function returns an array of all parameters provided to function?

func_get_args( ) returns an array of all parameters provided to the function, func_num_args( ) returns the number of parameters provided to the function, and func_get_arg( ) returns a specific argument from the parameters.

What is a parameter name in Python?

Parameters are the input variables bounded by parentheses when defining a function, whereas arguments are the values assigned to these parameters when passed into a function (or method) during a function call.

What are parameters in Javascript?

A parameter is a named variable passed into a function. Parameter variables are used to import arguments into functions. For example: function example(parameter) { console.


2 Answers

I realize people linked to other questions which mentioned PostSharp, but I couldn't help posting the code that solved my problem (using PostSharp) so other people could benefit from it.

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

Simply adding the Trace attribute to a method will cause very nice debugging information to be output, like so:

Debug: Entering MyClass.MyMethod.  x = 44 someString = asdf qwer 1234 anotherFloat = 3.14 theBool = True Return Value: 45 Debug: Leaving MyClass.MyMethod. 
like image 135
Mark Carpenter Avatar answered Oct 08 '22 18:10

Mark Carpenter


It's theoretically possible with a debug build and optimization turned off, but practically speaking, I suggest you want some source code rewriting pass.

People are going to keep telling you reflection will work when it won't, so here is the function that's actually capable of getting argument values. It's not likely to work reliably with optimization enabled (for example, there might not even be a stack frame when inlining is on) and getting a debugger installed so you can call that function won't be nearly as simple as you were hoping.

like image 21
Ben Voigt Avatar answered Oct 08 '22 20:10

Ben Voigt