Initializing Events Using Initializer Syntax

I often want to write something like this:

new Form { Text = "Caption", Controls = { new Button { Text = "Button 1", Click = (s, e) => MessageBox.Show("Button 1 Clicked"), Location = new Point(10, 10) }, new Button { Text = "Button 2", Click = new EventHandler(Button2Clicked), Location = new Point(10, 40) }, new Button { Text = "Button 3", Click = Button3Clicked, Location = new Point(10, 70) }, }, } 

The initializer syntax is just sugar, so why can't the compiler determine how to generate code to subscribe to events?

Give me some sugar, baby!

When the initializer syntax was invented, someone had to think about events and reject them. I try to imagine what could be a rationale, and I start empty.

Is it because an event is a multi-sheeted object that can have more than one subscriber? No, this is the initialization process; There can be no other subscribers. [Updated] Not true, initializers are applied after construction, and the object subscribes to its own events .

Note to Eric: I heard why C # does not implement the X-speech function. In this case, someone was already there, implementing initializers.

Update

There seems to be a contradiction / confusion because I used Click = in my example. The actual syntax is not relevant to the question. Click += would also be easy, which reflects how you usually add a handler. I prefer the former because it is consistent with the rest of the initializer syntax, but in the end I don’t care if I can subscribe to an event in the initializer list.

Another update

I understand that adding a function is now probably unlikely. The first question that comes to mind is that Intellisense needs to be updated. There are probably many other things that would make it difficult to add this feature now. My question is: why didn’t they add it in the first place. There must have been something irresistible that triggered a no vote.

+7
source share
4 answers

I see no reason why they could not provide this small teaspoon of sugar, I think they just did not!

A lot of syntactic sugar is already present in events, if you simply declare an event in the class without providing your own implementation, the compiler will provide you with a delegate support field and also add / remove "method" implementations. In addition, when you add an event handler, the compiler uses delegate output, allowing you to simply point to a method rather than create a delegate representing this method.

Interestingly, Mono C # allows you to add an event handler to the object initializer:

http://tirania.org/blog/archive/2009/Jul-27-1.html

Time to switch to Mono; -)

+6
source

Try just assigning an event:

 Click = (o,e) => { <CODE> } 

Does not work. Initializers work only with things that you can directly assign. This is because events should be able to notify anyone they want (you are not allowed to delete someone else for this event in an accident).

I am not sure if these are their arguments, but it works for me.

+2
source

There is a big difference between fields and events . There's a great article here that outlines the differences, but the answer to your question is: a field can be assigned a value; the event is like a field, but it is a completely different beast.

Edit

From an article related to:

We saw that the keyword event is a delegate declaration modifier that allows it to be included in the interface, restrains its call from the class declaring it, provides it with a couple of custom accessors (add and remove) and forces the delegate's signature

Remember that event is a shortcut; Behind the scenes, the compiler creates an object with the add() and remove() methods. How:

 public class Button { public event EventHandler Click { void add {...} void remove {...} } } 

Perhaps this will give some idea ...:

 Button btn = new Button {Click += (s, e) => MessageBox.Show("hello")}; 

The error message you get is "Unable to initialize the 'Button' type with the collection initializer because it does not implement IEnumerable"


One more note ... if you assign an event handler from the form, you can do this:

 this.button1.Click += (s, e) => this.textBox1.Text = e.ToString(); 

You cannot access form variables from generated code. I get where you came from and I disagree ... what you do can work. I suppose I want to say that there are reasons why the decision was not made to make it work.

+2
source

Yes, it must be part of the language!

But here is a complicated workaround that allows you to subscribe to events in the initializer list ...

 public class TestClass { public class MyButton : Button { public EventHandler ClickSubscriber { get { return null; } set { Click += value; } } } public static void RunTest() { new Form { Text = "Caption", Controls = { new MyButton { ClickSubscriber = (s, e) => MessageBox.Show("Button 1 Clicked"), }, }, }; } } 
+1
source

All Articles