Assigning events in object initializer
This didn't make C# 6 or C# 7 (since the original question), however it hasn't been decided against. There is an issue on GitHub that tracks the language proposal. You can vote for it there, as well as follow links into previous discussion around the feature.
https://github.com/dotnet/csharplang/issues/307
If you'd like to see this feature, add a thumbs-up to the issue to help raise its visibility.
The proposed syntax is:
var timer = new DispatcherTimer {
Tick += delegate {},
Interval = TimeSpan.FromSeconds(1d),
};
As far the external contract is concerned, an event doesn't have a setter, only add
and remove
methods - subscribers can register and unregister from the event, and the publishing object decides when to invoke the callbacks by 'raising' the event. Consequently, the idea of "assigning an event", in general, is meaningless.
However, when you declare an event in a class, the C# compiler provides you with what is really a convenience-feature: when you don't provide your own implementation, it creates a private, backing delegate-field for you, along with the appropriate add / remove implementations . This allows you to "set the event" (really the backing field) within the class, but not outside it. To understand this, consider:
public class Foo
{
// implemented by compiler
public event EventHandler MyEvent;
public static Foo FooFactory(EventHandler myEventDefault)
{
// setting the "event" : perfectly legal
return new Foo { MyEvent = myEventDefault };
}
}
public class Bar
{
public static Foo FooFactory(EventHandler myEventDefault)
{
// meaningless: won't compile
return new Foo { MyEvent = myEventDefault };
}
}
public class Baz
{
// custom implementation
public event EventHandler MyEvent
{
add { } // you can imagine some complex implementation here
remove { } // and here
}
public static Baz BazFactory(EventHandler myEventDefault)
{
// also meaningless: won't compile
return new Baz { MyEvent = myEventDefault };
}
}
You can only use the operators +=
or -=
to an event outside its owner class.
public class Data
{
public event EventHandler OnSave = (s,e) =>
{
//do something important!
};
public void Save()
{
OnSave(this,null);
//do save
}
}
//outside the class
Data data = new Data { OnSave = null }; //compile error
data.OnSave = SomeMethodElse; //compile error
data.OnSave += MyCustomActionsOnSave; //ok
data.Save();
You can't remove the OnSave
action defined in the class. You can only add/remove your own OnSave
actions outside the class. If you remove the event
keyword, the OnSave
will be no longer an event, but an ordinary delegate. Then you can do anything including assigning value outside the class.