30

How can I get the values of parms (in a loop using reflection). In previous question, someone showed me how to loop through the parms using reflection.

static void Main(string[] args)
{
    ManyParms("a","b","c",10,20,true,"end");
    Console.ReadLine(); 
}

static void ManyParms(string a, string b, string c, int d, short e, bool f, string g)
{
    var parameters = MethodBase.GetCurrentMethod().GetParameters();
    foreach (ParameterInfo parameter in parameters)
    {
        string parmName = parameter.Name;
        Console.WriteLine(parmName); 
        //Following idea required an object first 
        //Type t = this.GetType();
        //t.GetField(parmName).GetValue(theObject));

    }
}

If you must know why I want to do this, please see here: .NET Reflection of all method parameters


Thanks all - it seems like in Python, PERL, PHP this would be easy.
Even though it may not be reflection, if I use reflection to get the field name, seems like there would be an easy dynamic way to get the value based on the name. I haven't tried AOP (Aspect Oriented Programming) the solutions yet. This is one of those things that if I can't do it in an hour or two, I probably won't do it.

HotN
  • 4,216
  • 3
  • 40
  • 51
NealWalters
  • 17,197
  • 42
  • 141
  • 251
  • Maybe something could be done by inspecting via reflection the state machine that is generated when you use an IEnumerable? Just an idea I wouldn't know how to realize myself :-) (Commenting here because of a duplicate question today) – Jbjstam Oct 10 '16 at 16:40

7 Answers7

41

You can hack your way around this by creating an anonymous type inside your method and taking advantage of projection initialisers. You can then interrogate the anonymous type's properties using reflection. For example:

static void ManyParms(
    string a, string b, string c, int d, short e, bool f, string g)
{
    var hack = new { a, b, c, d, e, f, g };

    foreach (PropertyInfo pi in hack.GetType().GetProperties())
    {
        Console.WriteLine("{0}: {1}", pi.Name, pi.GetValue(hack, null));
    }
}
LukeH
  • 263,068
  • 57
  • 365
  • 409
  • 8
    That requires you to change the contents of your method. If you're going to do that, you can just report the values anyway. This syntax makes it slightly easier to do so, but I doubt it'll really help the OP. – Jon Skeet Dec 08 '09 at 17:40
  • 1
    @Jon: You're right, of course, but this is *a lot* less typing than doing it manually, and because there aren't multiple hardcoded lines like `Console.WriteLine("a: " + a)` etc, there's much less scope for error. – LukeH Dec 08 '09 at 17:49
  • This would be a great thing to do in something like PostSharp or Fody. – Rob Sutherland Aug 19 '15 at 14:27
24

You can't, basically - at least not without hooking into the debugger/profiling API.

In theory there could be some way of the StackFrame class exposing parameter values, but it doesn't - and I suspect that in order to do so, you'd have to remove several optimisations.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
4

Have you considered using AOP, like PostSharp?

It can get access to argument values before your method executes, and your code would thus be reduced to a reusable attribute class, and an attribute applied to the methods that needs to have this check.

NealWalters
  • 17,197
  • 42
  • 141
  • 251
Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
3

You can't via reflection, and you shouldn't do it anyways.

If you need this kind of functionality, use a proxy, e.g. via a RealProxy implementation which intercepts the call for you. Then, you can check and modify any parameter before the actual call is made (or even not do the original call at all, that's up to you).

Lucero
  • 59,176
  • 9
  • 122
  • 152
  • I'll look into this if I have more time. If you see my referenced post above though, I'm using Microsoft Host Integration Server and specifically HIP - and not sure how the proxy would play with those guys. – NealWalters Dec 08 '09 at 16:38
3

You cannot do that. Reflection works on meta-data embedded during compilation and at that time parameter values are not known.

RaYell
  • 69,610
  • 20
  • 126
  • 152
2

You cannot get the value of the method's parameters using reflection. Because reflection returns the metadata information. If you'd like to get the value of a specific field or property you need to use an instance as well (like you already know).

There are several ways to get a parameter's value using the inner plumbing of the .NET framework - namely profiler API and debugger API.

You can use AOP for what you're trying to do, there is a Codeplex project called CThru that might help you - using CThru you can intercept the method when it's being called and get the parameters it was called with.

Dror Helper
  • 30,292
  • 15
  • 80
  • 129
1

PostSharp Diagnostics Toolkit supports IncludeParameterValue option.

If you want more details up to creating mini dump,

see Accessing stack traces with MDbgEngine and PADRE and Creating a custom PostSharp aspect (with IL transformation)

Michael Freidgeim
  • 26,542
  • 16
  • 152
  • 170