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");
}
}
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.
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.
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.
Microsoft MVP, MCTS, PostSharp MVP,