I see this question a lot. The developer has created an aspect and when they are stepping through they are seeing that the advice method arguments are null. The most common example of this is the MethodExecutionArgs.Exception. We can easily reproduce this “issue”.

Example

If you compile this code and step through it, the args parameter will be null.

[LogAspect]
class Program
{
    static void Main(string[] args)
    {
        throw new Exception("test exception");
    }
}

[Serializable]
public class LogAspect : OnExceptionAspect
{
    public override void OnException(MethodExecutionArgs args)
    {
        Console.Write("There was an error");
    }
}

PostSharpNullArgs1

So what’s going on? Well if you use ILSpy and look at the compiled result, you’ll see that PostSharp uses optimizations that include ignoring unused properties.

PostSharpNullArgsILSpy1

See how the OnException method has been decorated with multiple MethodExecutionAdviceOptimizations flags? The entire list for this aspect is:

MethodExecutionAdviceOptimization(
MethodExecutionAdviceOptimizations.IgnoreGetMethod 
| MethodExecutionAdviceOptimizations.IgnoreSetFlowBehavior
| MethodExecutionAdviceOptimizations.IgnoreGetArguments
| MethodExecutionAdviceOptimizations.IgnoreSetArguments
| MethodExecutionAdviceOptimizations.IgnoreGetInstance 
| MethodExecutionAdviceOptimizations.IgnoreSetInstance
| MethodExecutionAdviceOptimizations.IgnoreGetException 
| MethodExecutionAdviceOptimizations.IgnoreGetReturnValue
| MethodExecutionAdviceOptimizations.IgnoreSetReturnValue 
| MethodExecutionAdviceOptimizations.IgnoreGetMethodExecutionTag
| MethodExecutionAdviceOptimizations.IgnoreSetMethodExecutionTag 
| MethodExecutionAdviceOptimizations.IgnoreEventArgs
)

Notice the IgnoreGetException flag? That’s why it’s null when stepping through the aspect. Change the aspect to

[LogAspect]
class Program
{
    static void Main(string[] args)
    {
        throw new Exception("test exception");
    }
}

[Serializable]
public class LogAspect : OnExceptionAspect
{
    public override void OnException(MethodExecutionArgs args)
    {
        Exception e = args.Exception; //Now we're using Exception so it won't be null
        Console.Write("There was an error");
    }
}

and rebuild. When you step through this time, args is not null and neither is args.Exception.

PostSharpNullArgs2

Looking at ILSpy again, you no longer see the IgnoreGetException flag.

MethodExecutionAdviceOptimization(
MethodExecutionAdviceOptimizations.IgnoreGetMethod
| MethodExecutionAdviceOptimizations.IgnoreSetFlowBehavior
| MethodExecutionAdviceOptimizations.IgnoreGetArguments
| MethodExecutionAdviceOptimizations.IgnoreSetArguments
| MethodExecutionAdviceOptimizations.IgnoreGetInstance
| MethodExecutionAdviceOptimizations.IgnoreSetInstance
| MethodExecutionAdviceOptimizations.IgnoreGetReturnValue
| MethodExecutionAdviceOptimizations.IgnoreSetReturnValue
| MethodExecutionAdviceOptimizations.IgnoreGetMethodExecutionTag
| MethodExecutionAdviceOptimizations.IgnoreSetMethodExecutionTag
)

Answer

So why are the arguments null? Because you’re not using them.

kick it on DotNetKicks.com

Advertisements