views:

1439

answers:

2

I would like to be able to obtain all the parameter values from the StackFrame in .NET. A bit like how you're able to see the values in the CallStack when in the VS debugger. My approach has concentrated on using the StackFrame class and then to reflect over a ParamaterInfo array. I've had success with reflection and properties, but this is proving a bit trickier.

Does anyone have an approach for achieving this?

Code so far looks like this...

class Program
{
 static void Main(string[] args)
 {
  A a = new A();
  a.Go(1);
 }
}

public class A
{
 internal void Go(int x)
 {
  B b = new B();
  b.Go(4);
 }
}


public class B
{

 internal void Go(int y)
 {
  Console.WriteLine(GetStackTrace());

 }
 public static string GetStackTrace()
 {
  StringBuilder sb = new StringBuilder();
  StackTrace st = new StackTrace(true);
  StackFrame[] frames = st.GetFrames();

  foreach (StackFrame frame in frames)
  {
   MethodBase method = frame.GetMethod();

   sb.AppendFormat("{0} - {1}",method.DeclaringType, method.Name);
   ParameterInfo[] paramaters = method.GetParameters();
   foreach (ParameterInfo paramater in paramaters)
   {
    sb.AppendFormat("{0}: {1}", paramater.Name, paramater.ToString());
   }
   sb.AppendLine();
  }


  return sb.ToString();
 }

}

Output looks like this:

SfApp.B - GetStackTrace
SfApp.B - Go
y: Int32 y
SfApp.A - Go
x: Int32 x
SfApp.Program - Main
args: System.String[] args

I'd like it to look more like this:

SfApp.B - GetStackTrace
SfApp.B - Go
y: 4
SfApp.A - Go
x: 1
SfApp.Program - Main

Edit: Thanks for both answers; just for a bit of context my plan was to try and use this when I throw my own exceptions. I'll look at your suggestions in more detail and see if I can see it fitting.

2nd Edit: Still looking for an answer for this one

+1  A: 

You can't do this with StackFrames.

One possibility would be to use an interception framework, or you write your own with .net's proxies. I did it once and documented it here: http://tdanecker.blogspot.com/2007/09/interception-with-proxies.html

Thomas Danecker
+1  A: 

It seems it can't be done that way. It will only provide meta information about the method and it's parameters. Not the actual value at the time of the callstack.

Some suggest deriving your classes from ContextBoundObject and use IMessageSink to be notified off all method calls and the values of the parameters. This is normally used for .Net Remoting.

Another suggestion might be to write a debugger. This is how the IDE gets its information. Microsoft has Mdbg of which you can get the source code. Or write a CLR profiler.

Lars Truijens