| Severity | Error |
| Reported by | PostSharp |
| Message | Cannot set the property <Property> of the multicast attribute [<AttributeType>] on "<Declaration>": the [MulticastAttributeUsage] of the attribute class sets Inheritance, and an instance cannot override it. |
Cause
The AttributeInheritance property of a multicast attribute determines whether the attribute is inherited by derived classes, overriding methods and implementations of interfaces. When the class of the attribute does not decide, each instance can set it. When the [MulticastAttributeUsage] of the attribute class sets Inheritance, the aspect developer has decided for every usage, and PostSharp reports PS0108 when an instance applied in your code sets AttributeInheritance to another value. Setting it to the same value is allowed.
<Property> is always AttributeInheritance. Because the attribute is invalid, PostSharp also stops with PS0055.
In the following example, the [Log] aspect is never inherited, but its usage on OrderProcessor.Process asks for strict inheritance.
using System;
using PostSharp.Aspects;
using PostSharp.Extensibility;
using PostSharp.Serialization;
namespace Errors.PS0108_Error;
// The aspect developer decides that the aspect is never inherited.
[PSerializable]
[MulticastAttributeUsage( MulticastTargets.Method, Inheritance = MulticastInheritance.None )]
public class LogAttribute : OnMethodBoundaryAspect
{
public override void OnEntry( MethodExecutionArgs args )
{
Console.WriteLine( $"Entering {args.Method.DeclaringType!.Name}.{args.Method.Name}." );
}
}
public class OrderProcessor
{
[Log( AttributeInheritance = MulticastInheritance.Strict )] // The usage tries to change the inheritance of the aspect.
public virtual void Process( string product )
{
Console.WriteLine( $"Processing {product}." );
}
}
public class PriorityOrderProcessor : OrderProcessor
{
public override void Process( string product )
{
Console.WriteLine( $"Processing {product} first." );
}
}
public static class Program
{
public static void Main()
{
new OrderProcessor().Process( "Coffee" );
new PriorityOrderProcessor().Process( "Tea" );
}
}
error PS0108: PS0108_Error.cs(22,25): Cannot set the property AttributeInheritance of the multicast attribute [Errors.PS0108_Error.LogAttribute] on "Errors.PS0108_Error.OrderProcessor.Process(System.String)": the [MulticastAttributeUsage] of the attribute class sets Inheritance, and an instance cannot override it.
error PS0055: The processing of multicast attributes cannot continue because of the previous errors.
Resolution
- Remove AttributeInheritance from the attribute, and apply the attribute to the derived declarations that need it.
- When the attribute class is yours and its usages must choose, remove Inheritance from its
[MulticastAttributeUsage].
In the following example, the [Log] aspect is applied to the overriding method too.
using System;
using PostSharp.Aspects;
using PostSharp.Extensibility;
using PostSharp.Serialization;
namespace Errors.PS0108_Fixed;
// The aspect developer decides that the aspect is never inherited.
[PSerializable]
[MulticastAttributeUsage( MulticastTargets.Method, Inheritance = MulticastInheritance.None )]
public class LogAttribute : OnMethodBoundaryAspect
{
public override void OnEntry( MethodExecutionArgs args )
{
Console.WriteLine( $"Entering {args.Method.DeclaringType!.Name}.{args.Method.Name}." );
}
}
public class OrderProcessor
{
[Log]
public virtual void Process( string product )
{
Console.WriteLine( $"Processing {product}." );
}
}
public class PriorityOrderProcessor : OrderProcessor
{
[Log] // The aspect is applied to the overriding method explicitly.
public override void Process( string product )
{
Console.WriteLine( $"Processing {product} first." );
}
}
public static class Program
{
public static void Main()
{
new OrderProcessor().Process( "Coffee" );
new PriorityOrderProcessor().Process( "Tea" );
}
}
Entering OrderProcessor.Process.
Processing Coffee.
Entering PriorityOrderProcessor.Process.
Processing Tea first.
See Also
Reference
AttributeInheritance
Inheritance
MulticastInheritance
Other Resources
Adding Aspects to Derived Classes and Methods Using Attributes
Understanding Aspect Inheritance