C# Feature Suggestion: Attaching Properties to Events
While working on the next version of the my
Commonly Used .NET Coding Patterns in CodeDom article, I've come up with a nice idea for the next version of C# (or any other language for that matter).
Consider the following scenario:
A doctor's office is handled by a class named
DoctorsOffice. The class has a property of type
PatientsQueue which is a queue of patients (First In, First Out), which in turn exposes an event called
PatientEnteredQueue (which has one parameter - the
Patient object). This event is called whenever someone walks in the door.
Some objects consume this event, such as the
BlondeSecretary (who checks if the patient has an appointment) and the
WeirdDudeWhosAlwaysThereForSomeReason (who just gives the new guy a weird sideways look).
Whenever a new patient enters the office, the
PatientsQueue.Queue method is called which raises the
PatientEnteredQueue event.
Once every few new patients, one of them asks the question "Who's last in the queue?" just to know how long they'll have to wait before seeing the doctor. This is implemented by the
WhosLast property on
DoctorsOffice.
class DoctorsOffice
{
public PatientsQueue Queue { get; }
public Patient WhosLast { get; private set; }
}
class PatientsQueue
{
public void Queue(Patient p);
public event PatientEvent PatientEnteredQueue;
}
A very logical approach to this would be to consume the event inside
DoctorsOffice and set the
WhosLast property to the
Patient value. The problem here is that you would have to use a method in the middle, first to consume the event and then to set the property.
public DoctorsOffice()
{
this.Queue.PatientEnteredQueue += this.AnotherPatientHasEntered;
}
private void AnotherPatientHasEntered(Patient p)
{
this.WhosLast = p;
}
This is a cumbersome approach that can be bypassed by adding a simple feature - adding the ability to attach properties to events:
public DoctorsOffice()
{
this.Queue.PatientEnteredQueue += this.WhosLast;
}
Since properties are implemented as methods, the compiler could choose which one it would like to use (depending on the signature of the delegate).
If the property returns an instance of the same delegate as the one being attached to, this would cause a problem and then C# 1.0's syntax would have to be used, after a warning (the default would be to use the return value, rather than attach the property, for backwards compatability's sake):
public delegate MyDelegate MyDelegate();
private MyDelegate MyDelegateEvent
{
get
{
// Do work...
}
}
private void Foo()
{
this.MyDelegateEvent += this.DelegateInstanceReturningProperty; // Warning. Return value used by default.
this.MyDelegateEvent += new MyDelegate(this.DelegateInstanceReturningProperty);
}