| Severity | Error |
| Reported by | PostSharp |
| Message | Cannot bind field "<Field>" to type "<TargetType>": cannot find an event named <EventNames> in type "<TargetType>" or its ancestors. |
Cause
An aspect imports an event of its target class with a field of type Event<TDelegate> annotated with ImportMemberAttribute. PostSharp looks for an event with the name given to the attribute in the target type and in its base types. When the IsRequired property is true, PostSharp reports LA0082 for each target type where it finds no such event. When IsRequired is false, which is the default, the field stays null instead.
The event is not found when no event has this name, for example because of a typo, or when the event is a private event of a base class.
<EventNames> lists the names given to the attribute, each in quotes. PostSharp reports the error on the target type, not on the field of the aspect. When the event exists but its delegate type differs from the type argument of the field, PostSharp reports LA0083 instead.
In the following example, the [TraceChanges] aspect imports a Changed event, but the event of Customer is named NameChanged.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0082_Error;
[PSerializable]
public class TraceChangesAttribute : InstanceLevelAspect
{
// Customer has no event named Changed.
[ImportMember( "Changed", IsRequired = true )]
public Event<EventHandler>? NameChanged;
public override void RuntimeInitializeInstance()
{
this.NameChanged!.Add( ( sender, args ) => Console.WriteLine( "The name changed." ) );
}
}
[TraceChanges]
public class Customer
{
private string name = "Alice";
public event EventHandler? NameChanged;
public string Name
{
get => this.name;
set
{
this.name = value;
this.NameChanged?.Invoke( this, EventArgs.Empty );
}
}
}
public static class Program
{
public static void Main()
{
new Customer().Name = "Bob";
}
}
error LA0082: LA0082_Error.cs(22,14): Cannot bind field "Errors.LA0082_Error.TraceChangesAttribute.NameChanged" to type "Errors.LA0082_Error.Customer": cannot find an event named "Changed" in type "Errors.LA0082_Error.Customer" or its ancestors.
Resolution
- Correct the name given to ImportMemberAttribute, or pass several names when the event can have one of several names.
- Make the event of the base class accessible to the target class, for example
protectedinstead ofprivate. - When the aspect can work without the event, set IsRequired to
falseand check that the field is notnullbefore using it.
In the following example, the attribute gives the name of the NameChanged event, and the handler that the aspect adds runs when the name changes.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0082_Fixed;
[PSerializable]
public class TraceChangesAttribute : InstanceLevelAspect
{
// The attribute gives the name of the event of Customer.
[ImportMember( "NameChanged", IsRequired = true )]
public Event<EventHandler>? NameChanged;
public override void RuntimeInitializeInstance()
{
this.NameChanged!.Add( ( sender, args ) => Console.WriteLine( "The name changed." ) );
}
}
[TraceChanges]
public class Customer
{
private string name = "Alice";
public event EventHandler? NameChanged;
public string Name
{
get => this.name;
set
{
this.name = value;
this.NameChanged?.Invoke( this, EventArgs.Empty );
}
}
}
public static class Program
{
public static void Main()
{
new Customer().Name = "Bob";
}
}
The name changed.
See Also
Reference
ImportMemberAttribute
Event<TDelegate>
Other Resources