tags:

views:

349

answers:

6

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: http://stackoverflow.com/questions/1862433/net-reflection-of-all-method-parameters

Thanks,

Neal Walters


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.

+8  A: 

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
+4  A: 

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
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
+2  A: 

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

RaYell
But you can use reflection to get values of properties in objects - which are not known at compile time.
NealWalters
+3  A: 

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.

Lasse V. Karlsen
+2  A: 

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
+2  A: 

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
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
@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