| Severity | Error |
| Reported by | PostSharp |
| Message | The [State] slot "<Slot>" has the type "<Type>" in the parameter "<Parameter>" of the advice "<Advice>", but the type "<OtherType>" in the parameter "<OtherParameter>" of the advice "<OtherAdvice>". All parameters bound to the same slot must have the same type. |
Cause
A parameter annotated with StateAttribute is bound to a variable that the advices of one group share for one execution of the target method. The variable is identified by its slot: the name of the parameter, or the slot name given to the StateAttribute constructor. Since one variable stores the value, all the parameters bound to a slot must have exactly the same type, whether they are passed by value or by reference. A base type, such as object, is not accepted.
PostSharp reports LA0215 when a parameter bound to a slot has another type than the first parameter bound to this slot in the group. <Parameter> and <Advice> designate the parameter that PostSharp reports, and <OtherParameter> and <OtherAdvice> the first parameter bound to the slot.
In the following example, the entry advice stores a Stopwatch in the stopwatch slot, and the exit advice reads the slot as an object.
using System;
using System.Diagnostics;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0215_Error;
[PSerializable]
public class MeasureAttribute : MethodLevelAspect
{
[OnMethodEntryAdvice]
public static void OnEntry( [State( StateScope.MethodInvocation )] out Stopwatch stopwatch )
{
stopwatch = Stopwatch.StartNew();
}
[OnMethodExitAdvice]
public static void OnExit(
[DeclarationName] string methodName,
// The slot "stopwatch" is a Stopwatch in the entry advice, but an object here.
[State( StateScope.MethodInvocation )] object stopwatch )
{
Console.WriteLine( $"{methodName} completed, the stopwatch is running: {((Stopwatch) stopwatch).IsRunning}." );
}
}
public class ReportService
{
[Measure]
public void Generate() => Console.WriteLine( "Generating the report." );
}
public static class Program
{
public static void Main()
{
new ReportService().Generate();
}
}
error LA0215: LA0215_Error.cs(22,55): The [State] slot "stopwatch" has the type "object" in the parameter "stopwatch" of the advice "Errors.LA0215_Error.MeasureAttribute.OnExit(System.String, System.Object)", but the type "System.Diagnostics.Stopwatch" in the parameter "stopwatch" of the advice "Errors.LA0215_Error.MeasureAttribute.OnEntry(System.Diagnostics.Stopwatch@)". All parameters bound to the same slot must have the same type.
Resolution
Give the same type to all the parameters bound to the slot. If the advices need different variables, give them different slots, by renaming a parameter or with the slot name argument of the StateAttribute constructor.
In the following example, both advices bind the slot with the Stopwatch type.
using System;
using System.Diagnostics;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0215_Fixed;
[PSerializable]
public class MeasureAttribute : MethodLevelAspect
{
[OnMethodEntryAdvice]
public static void OnEntry( [State( StateScope.MethodInvocation )] out Stopwatch stopwatch )
{
stopwatch = Stopwatch.StartNew();
}
[OnMethodExitAdvice]
public static void OnExit(
[DeclarationName] string methodName,
// The slot "stopwatch" has the same type in both advices.
[State( StateScope.MethodInvocation )] Stopwatch stopwatch )
{
Console.WriteLine( $"{methodName} completed, the stopwatch is running: {stopwatch.IsRunning}." );
}
}
public class ReportService
{
[Measure]
public void Generate() => Console.WriteLine( "Generating the report." );
}
public static class Program
{
public static void Main()
{
new ReportService().Generate();
}
}
Generating the report.
Generate completed, the stopwatch is running: True.
See Also
Reference
Other Resources