| Severity | Error |
| Reported by | PostSharp |
| Message | Cannot introduce method "<Method>" into type "<TargetType>" because it is already defined in type "<DeclaringType>", and the IsVirtual property of the introduction does not match whether this method is virtual. |
Cause
When an aspect introduces a method with IntroduceMemberAttribute and sets its OverrideAction to OverrideOrFail or OverrideOrIgnore, and the target type itself already defines this method, PostSharp replaces the body of the existing method instead of adding a new one. The existing method keeps its modifiers, so it cannot become virtual or stop being virtual.
When you set the IsVirtual property of the introduction explicitly, PostSharp compares it with the existing method, which counts as virtual when it is virtual and not sealed. When they differ, PostSharp reports LA0071. When you do not set IsVirtual, the existing method keeps its virtuality and PostSharp reports nothing.
The message concerns only a method of the target type, so <DeclaringType> is always <TargetType>. For a property or an event, PostSharp checks each accessor, so <Method> is the name of the accessor, such as get_Name.
In the following example, the [Describable] aspect introduces a virtual Describe method into Customer, which already defines a non-virtual Describe method.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0071_Error;
[PSerializable]
public class DescribableAttribute : InstanceLevelAspect
{
[IntroduceMember( OverrideAction = MemberOverrideAction.OverrideOrFail, IsVirtual = true )]
public string Describe() => $"Instance of {this.Instance!.GetType().Name}";
}
[Describable]
public class Customer
{
public string Name { get; set; } = "Alice";
// The method is not virtual, but the introduction requires a virtual method.
public string Describe() => $"Customer {this.Name}";
}
public static class Program
{
public static void Main()
{
Console.WriteLine( new Customer().Describe() );
}
}
error LA0071: LA0071_Error.cs(21,19): Cannot introduce method "Describe" into type "Errors.LA0071_Error.Customer" because it is already defined in type "Errors.LA0071_Error.Customer", and the IsVirtual property of the introduction does not match whether this method is virtual.
Resolution
- Give the existing method the virtuality that the introduction requires: add or remove the
virtualmodifier, or remove thesealedmodifier. - Remove the IsVirtual property from the introduction, so that the existing method keeps its own virtuality.
In the following example, Customer.Describe is virtual, so the aspect replaces it.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0071_Fixed;
[PSerializable]
public class DescribableAttribute : InstanceLevelAspect
{
[IntroduceMember( OverrideAction = MemberOverrideAction.OverrideOrFail, IsVirtual = true )]
public string Describe() => $"Instance of {this.Instance!.GetType().Name}";
}
[Describable]
public class Customer
{
public string Name { get; set; } = "Alice";
// The method is virtual, as the introduction requires, so the aspect replaces it.
public virtual string Describe() => $"Customer {this.Name}";
}
public static class Program
{
public static void Main()
{
Console.WriteLine( new Customer().Describe() );
}
}
Instance of Customer
See Also
Reference
IntroduceMemberAttribute
MemberOverrideAction
Other Resources
Introducing Interfaces, Methods, Properties and Events into Existing Classes