| Severity | Error |
| Reported by | PostSharp |
| Message | Aspect "<Aspect>" cannot be applied to field "<Field>" because it is constant. |
Cause
A location validation aspect, which implements ILocationValidationAspect<T>, validates the value of a field each time it is assigned. A const field is never assigned at run time: the compiler copies its value into the code that reads it. There is no assignment to validate, so PostSharp reports LA0127 and skips the aspect.
In the following example, the [NotEmpty] aspect is applied to the DefaultCarrier constant.
using System;
using PostSharp.Aspects;
using PostSharp.Reflection;
using PostSharp.Serialization;
namespace Errors.LA0127_Error;
[PSerializable]
public class NotEmptyAttribute : LocationLevelAspect, ILocationValidationAspect<string>
{
public Exception? ValidateValue( string value, string locationName, LocationKind locationKind, LocationValidationContext context )
=> string.IsNullOrEmpty( value ) ? new ArgumentException( $"{locationName} cannot be empty.", locationName ) : null;
}
public class Shipment
{
// A constant cannot be assigned, so there is nothing to validate.
[NotEmpty]
public const string DefaultCarrier = "UPS";
[NotEmpty]
public string Carrier = DefaultCarrier;
}
public static class Program
{
public static void Main()
{
var shipment = new Shipment();
try
{
shipment.Carrier = "";
}
catch ( ArgumentException e )
{
Console.WriteLine( e.Message );
}
}
}
error LA0127: LA0127_Error.cs(19,25): Aspect "Errors.LA0127_Error.NotEmptyAttribute" cannot be applied to field "Errors.LA0127_Error.Shipment.DefaultCarrier" because it is constant.
Resolution
- Remove the aspect from the constant. Its value is fixed at compile time, so you can check it when you write it.
- When the value must be validated, declare a field or a property that is assigned at run time instead of a constant, and apply the aspect to it.
In the following example, the aspect is removed from the constant and stays on the Carrier field, where it rejects the empty value.
using System;
using PostSharp.Aspects;
using PostSharp.Reflection;
using PostSharp.Serialization;
namespace Errors.LA0127_Fixed;
[PSerializable]
public class NotEmptyAttribute : LocationLevelAspect, ILocationValidationAspect<string>
{
public Exception? ValidateValue( string value, string locationName, LocationKind locationKind, LocationValidationContext context )
=> string.IsNullOrEmpty( value ) ? new ArgumentException( $"{locationName} cannot be empty.", locationName ) : null;
}
public class Shipment
{
// The aspect is removed from the constant, whose value is fixed at compile time.
public const string DefaultCarrier = "UPS";
[NotEmpty]
public string Carrier = DefaultCarrier;
}
public static class Program
{
public static void Main()
{
var shipment = new Shipment();
try
{
shipment.Carrier = "";
}
catch ( ArgumentException e )
{
Console.WriteLine( e.Message );
}
}
}
Carrier cannot be empty. (Parameter 'Carrier')
See Also
Reference
ILocationValidationAspect<T>
LocationLevelAspect
Other Resources