| Severity | Error |
| Reported by | PostSharp |
| Message | Cannot introduce member "<Member>" into type "<TargetType>" because it is already defined in type "<DeclaringType>" and is not virtual or is sealed, so it cannot be overridden. |
Cause
When an aspect introduces a method, a property or an event with IntroduceMemberAttribute and sets its OverrideAction to OverrideOrFail, PostSharp overrides the member when a base type of the target type already defines it. An override is only possible when the member of the base type is virtual and not sealed. Otherwise, PostSharp reports LA0061.
<DeclaringType> is the base type that defines the existing member. For a property or an event, PostSharp checks each accessor, so <Member> is the name of the accessor, such as get_Name.
In the following example, the [Describable] aspect introduces a Describe method into Customer, but the Describe method of its base class Entity is not virtual.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0061_Error;
[PSerializable]
public class DescribableAttribute : InstanceLevelAspect
{
[IntroduceMember( OverrideAction = MemberOverrideAction.OverrideOrFail )]
public string Describe() => $"Instance of {this.Instance!.GetType().Name}";
}
public class Entity
{
// The method is not virtual, so the aspect cannot override it in a derived class.
public string Describe() => "Entity";
}
[Describable]
public class Customer : Entity
{
}
public static class Program
{
public static void Main()
{
Console.WriteLine( new Entity().Describe() );
Entity entity = new Customer();
Console.WriteLine( entity.Describe() );
}
}
error LA0061: LA0061_Error.cs(18,19): Cannot introduce member "Describe" into type "Errors.LA0061_Error.Customer" because it is already defined in type "Errors.LA0061_Error.Entity" and is not virtual or is sealed, so it cannot be overridden.
Resolution
- Make the member of the base type
virtual, or remove thesealedmodifier of its override, so that the introduced member can override it. - When you cannot change the base type, set the OverrideAction of the introduction to OverrideOrIgnore: PostSharp then skips the introduction instead of failing when the member cannot be overridden.
- Otherwise, rename the introduced member.
In the following example, Entity.Describe is virtual, so the method introduced into Customer overrides it.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0061_Fixed;
[PSerializable]
public class DescribableAttribute : InstanceLevelAspect
{
[IntroduceMember( OverrideAction = MemberOverrideAction.OverrideOrFail )]
public string Describe() => $"Instance of {this.Instance!.GetType().Name}";
}
public class Entity
{
// The method is virtual, so the aspect overrides it in the derived class.
public virtual string Describe() => "Entity";
}
[Describable]
public class Customer : Entity
{
}
public static class Program
{
public static void Main()
{
Console.WriteLine( new Entity().Describe() );
Entity entity = new Customer();
Console.WriteLine( entity.Describe() );
}
}
Entity
Instance of Customer
See Also
Reference
IntroduceMemberAttribute
MemberOverrideAction
Other Resources
Introducing Interfaces, Methods, Properties and Events into Existing Classes