-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Proposal] Events without the boilerplate #15282
Comments
Does the compiler generate an
|
What exactly do you mean by "how did it know which one you wanted?" why would it generate multiple event handlers? generally you have a single event handler per event not multiples.
Well, I dislike the boilerplate even more, can you suggest an alternative? I'd argue that creating an event handler many times, one per event lowers the clarity of the code multiple times more than getting used to to a new, more succinct syntax but if you have a better idea I'm all for it. 😄
|
First of all, Second, what As for boilerplate, I only add |
How common is it to actually advertise an For people who do want such generated methods I'd argue that this could be handled through a source generator rather than requiring changes to the language. |
Yeah, you right, didn't give that much thought.
Yeah, I know, I didn't know why I called it an event handler, my bad, will update.
Yeah got you, well the compiler will generate all of signatures or only the ones you call.
Well, I don't document these methods but sure, you got a point. |
In UI frameworks/library it's fairly common, it all depends on what you're doing.
Yeah, you probably right. |
I will note that the CLR provides a |
@HaloFour Yeah, I rarely write any VB.NET code, well didn't touch it for very long time but I think it's used there iirc, not sure. |
@HaloFour which really messed with my head when I switched to C#. Seems an eternity ago now... Also, I haven't missed indexed properties like I thought I would. :D |
@HaloFour I see, well, after you brought up the source generator feature I really feel like this proposal is not so attractive but the question is when we gonna see it. 😄 |
Indeed. Hopefully source generators are coming sooner rather than later as I think that they'll scratch a lot of itches. As for this proposal specifically, I think I'd prefer something a little more like auto-properties. public class Foo {
public event EventHandler MyEvent {
protected fire;
}
}
public class Bar : Foo {
public void DoSomething() {
base.MyEvent(this, default(EventArgs)); // invokes protected fire method
}
} I'm not bothering to get into the specific syntax details, e.g. whether or not |
@HaloFour I agree, I think this makes much more sense than putting the access modifier as part of the declaration, I like it, I'll update it after the Connect(); event haha.. |
@HaloFour Why specify the name |
The name isn't that important. I only reused the name of the method slot in the CLR metadata to illustrate the idea. |
Instead defining |
@vbcodec what could possibly go wrong? 😆 |
This is a great use case for generators. I don't think we would address this problem in isolation. |
@gafter Thanks, I agree. |
The Problem:
Today, we need to repeat ourselves quite a bit when we want to define an event, we need to have an event declaration and we need to create an event invoker.
The reasons we need to create an event invoker are as follow:
Ensure that the delegate instance we are calling to isn't null.
Events can't be invoked directly in derived classes so this help us achieve exactly that.
Finally, in case it's virtual it allows us to override it in derived classes even though events can actually be marked
virtual
.However, the event invoker itself, in many cases is fairly straightforward and the exact same pattern is repeated all over the place.
Here is a typical example:
The Solution:
So the solution is the ability to specify everything as part of the event declaration.
I'm thinking something like this:
public event <modifers> EventHandler<KeyboardKeyPressEventArgs> KeyPress;
Here are some rules that I think would make sense:
The access modifier cannot be public or internal.
Other modifiers such as virtual, static should be allowed.
So for the following statement:
The compiler will emit the foillowing code:
Event Invocation:
It's allowed to invoke delegates that are associated with events directly but only in classes that they were declared and as noted above it's not safe, also, attempting to do it from derived classes results an error.
However, with my proposal I'm hoping that the following would be possible
KeyPress('K')
.In this case under the hood the compiler will make a call to the generated event invoker as opposed to invoking the event itself.
Maybe it's going to be a bit weird that there's different rules based on the declaration of the event so maybe we can use some keyword here such as
raise
so it would look like thisraise KeyPress('K')
, not sure whether it make sense but maybe, I really hope that it wouldn't be necessary.Method Overriding:
I think that it wouldn't be possible to override the event invoker without some special syntax because the compiler is the one that generates it so I'm proposing the following syntax for it:
So after all these changes the above implementation would look like this:
Some notes:
In my experience, in most cases the
sender
is always the instance of the class so in this case I think that the compiler should always emitthis
.The signature of the generated event invoker should always match the signature of the class constructor that is passed to EventHandler or it should be parameterless in the case of EventHandler.
We generally use the following delegates EventHandler or EventHandler for events but it can actually be any delegate, does it make sense to restrict it to these two types? personally I think it does because after all this suppose to be a syntactic sugar, people that want more freedom/power can use the traditional way.
The text was updated successfully, but these errors were encountered: