4

How do you get the parameter NAMES of a method. The examples show you how to get the values of the parameters, but not the NAMES. I want to see parma = 99, parmb = 1. Not just 99, 1.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Diagnostics;
    using PostSharp.Aspects;

    namespace GettingParmNames
    {
        public class Program
        {
           static void Main(string[] args)
           {
               Foo myfoo = new Foo();
               int sum = myfoo.DoA(99, 1);
               Console.WriteLine(sum.ToString());

               Console.ReadKey();
           }
       }

    public class Foo
    {
        [ExceptionAspect]
        public int DoA(int parma, int parmb)
        {
            int retVal;
            try
            {
                retVal = parma + parmb;
                if (parma == 99)
                {
                    throw new Exception("Fake Exception");
                }

            }
            catch (Exception ex)
            {
                retVal = -1;
                throw new Exception("There was a problem");
            }

            return retVal;
        }
    }

    [Serializable]
    public class ExceptionAspect : OnExceptionAspect
    {
        public override void OnException(MethodExecutionArgs args)
        {
            string parameterValues = "";

            foreach (object arg in args.Arguments)
            {
                if (parameterValues.Length > 0)
                {
                    parameterValues += ", ";
                }

                if (arg != null)
                {
                    parameterValues += arg.ToString();
                }
                else
                {
                    parameterValues += "null";
                }
            }

            Console.WriteLine("Exception {0} in {1}.{2} invoked with arguments {3}", args.Exception.GetType().Name, args.Method.DeclaringType.FullName, args.Method.Name, parameterValues );
        }
    }

}
dannyrosalex
  • 1,794
  • 4
  • 16
  • 25
  • 1
    You want to get the in-code variable name? Like, you want it to print out 'parma'? Or you want it to print out whatever parma is? – Ideasthete Oct 06 '14 at 15:18

2 Answers2

6

You can access the method parameters' info in your OnException method by calling args.Method.GetParameters(). But usually it's better to initialize the data during compile time for performance reasons - in the CompileTimeInitialize method override.

[Serializable]
public class ExceptionAspect : OnExceptionAspect
{
    private string[] parameterNames;

    public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
    {
        parameterNames = method.GetParameters().Select(p => p.Name).ToArray();
    }

    public override void OnException(MethodExecutionArgs args)
    {
        StringBuilder parameterValues = new StringBuilder();

        for (int i = 0; i < args.Arguments.Count; i++)
        {
            if ( parameterValues.Length > 0 )
            {
                parameterValues.Append(", ");
            }

            parameterValues.AppendFormat(
                "{0} = {1}", parameterNames[i], args.Arguments[i] ?? "null");
        }

        // ...
    }
AlexD
  • 5,011
  • 2
  • 23
  • 34
1

Great answer from AlexD.

The following is a similar approach, giving you the argument names and values.

using System;
using System.Linq;
using System.Reflection;
using PostSharp.Aspects;

[Serializable]
public class LogWhenInvoked : MethodInterceptionAspect
{
    private string[] parameterNames;
    public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
    {
        parameterNames = method.GetParameters().Select(p => p.Name).ToArray();
    }

    public override void OnInvoke(MethodInterceptionArgs invocationArgs)
    {
        Console.WriteLine($"Entering {invocationArgs.Method.DeclaringType.Name}.{invocationArgs.Method.Name}");

        var args = parameterNames.Select((param, index) => new
        {
            Name = param,
            Value = invocationArgs.Arguments[index]
        })
        .ToList();

        invocationArgs.Proceed();
    }
}
Fidel
  • 7,027
  • 11
  • 57
  • 81