| Severity | Error |
| Reported by | PostSharp |
| Message | The parameter "<Parameter>" of the advice "<Advice>" is bound by [ImportMember] to an IMethodBinding, but the type "<TargetType>" has several methods named "<MethodName>": <Methods>. IMethodBinding selects a method by its name only. Import the method as a delegate, whose signature selects the overload. |
Cause
A parameter of type IMethodBinding annotated with ImportMemberAttribute imports a method of the target type by its name. IMethodBinding has no signature that could select one overload, so the name must designate a single method. When the target type, or one of its base types, has several methods of this name that are not generic and do not return by reference, PostSharp reports LA0266. An override does not count as a separate method.
PostSharp reports LA0266 whether or not IsRequired is true, on each target of the advice. <Methods> lists the overloads.
In the following example, the Order class has two Describe methods, and the [LogState] aspect imports Describe as an IMethodBinding.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0266_Error;
[PSerializable]
public class LogStateAttribute : MethodLevelAspect
{
// IMethodBinding selects the method by its name only, and Order has two Describe methods.
[OnMethodEntryAdvice]
public static void OnEntry( [This] object instance, [DeclarationName] string methodName,
[ImportMember( "Describe", IsRequired = true )] IMethodBinding describe )
{
Console.WriteLine( $"{methodName}: {describe.Invoke( ref instance, Arguments.Empty )}" );
}
}
public class Order
{
private string status = "New";
private int itemCount = 2;
public string Describe() => $"Order is {this.status}.";
public string Describe( bool detailed ) => detailed ? $"Order is {this.status} and has {this.itemCount} items." : this.Describe();
[LogState]
public void Ship()
{
this.status = "Shipped";
Console.WriteLine( "Order shipped." );
}
}
public static class Program
{
public static void Main()
{
new Order().Ship();
}
}
error LA0266: LA0266_Error.cs(30,17): The parameter "describe" of the advice "Errors.LA0266_Error.LogStateAttribute.OnEntry(System.Object, System.String, PostSharp.Aspects.IMethodBinding)" is bound by [ImportMember] to an IMethodBinding, but the type "Errors.LA0266_Error.Order" has several methods named "Describe": Errors.LA0266_Error.Order.Describe, Errors.LA0266_Error.Order.Describe(System.Boolean). IMethodBinding selects a method by its name only. Import the method as a delegate, whose signature selects the overload.
Resolution
- Import the method as a delegate. The delegate type selects the overload, as when C# converts a method group to a delegate: for an instance method, its first parameter receives the object, and the other parameters receive the arguments. Make the advice generic, with a
[This]parameter of the type parameter, when the delegate type must name the target type. - Rename one of the overloads in the target type.
In the following example, the delegate type Func<T, string> selects the method Describe().
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0266_Fixed;
[PSerializable]
public class LogStateAttribute : MethodLevelAspect
{
// The delegate type Func<T, string> selects the overload Describe().
[OnMethodEntryAdvice]
public static void OnEntry<T>( [This] T instance, [DeclarationName] string methodName,
[ImportMember( "Describe", IsRequired = true )] Func<T, string> describe )
{
Console.WriteLine( $"{methodName}: {describe( instance )}" );
}
}
public class Order
{
private string status = "New";
private int itemCount = 2;
public string Describe() => $"Order is {this.status}.";
public string Describe( bool detailed ) => detailed ? $"Order is {this.status} and has {this.itemCount} items." : this.Describe();
[LogState]
public void Ship()
{
this.status = "Shipped";
Console.WriteLine( "Order shipped." );
}
}
public static class Program
{
public static void Main()
{
new Order().Ship();
}
}
Ship: Order is New.
Order shipped.
See Also
Reference
ImportMemberAttribute
IMethodBinding
Other Resources