2👍
What you are talking about here are typically handled as events in C#, for example;
public class SomeType {
public event EventHandler SomeEvent;
protected virtual void OnSomeEvent() {
EventHandler handler = SomeEvent;
if(handler!=null) handler(this,EventArgs.Empty);
}
public void SomethingInteresting() {
// blah
OnSomeEvent(); // notify subscribers
// blap
}
// ...
}
With subscribers…
SomeType obj = new SomeType();
//...
obj.SomeEvent += /* some handler */
//...
the handler could be a method, but in your discussion of signatures etc, a common way of re-using existing methods with non-matching signatures is with anonymous methods:
obj.SomeEvent += delegate { this.Text = "Done!"; };
You can have a list of delegates:
List<SomeDelegateType> list = new List<SomeDelegateType>();
list.Add(...);
but this might be redundant because delegate instances are multicast – so you can do this more directly:
Action action = null;
action += delegate { Console.WriteLine("Did A");};
action += delegate { Console.WriteLine("Did B");};
action(); // does both A & B
Note that more complex delegate usage might involv incoming argument values – for example:
int i = 24;
Func<int,int,int> func = (x,y) => (x * i) + y;
int result = func(2, 3); // 51
By combining things like anonymous methods (or lambdas, as above) with captured variables, the issue of signatures having to match is rarely an issue – you can just wrap with a lambda to make the signature match (adding extra values or dropping arguments, as required).
Note that with events (in particular) the common approach is to keep the signature:
void SomeDelegateType(object sender, SomeArgsType args);
where SomeArgsType : EventArgs
– or use EventHandler<T>
which will do this for you.