How do I implement the Signals (from Django) concept in C#
I'm trying to implement signals from Django (http://docs.djangoproject.com/en/dev/topics/signals/), or its concept in C# to reduce/eliminate coupling/method dependencies.
So far, I'm replicating the code fine, up until the point whereby I realised methods ain't objects in C# as it is in Pyt开发者_开发百科hon. Then I thought of pointers, and then I realised that I can't have pointers to methods. The C# version of it are delegates.
Then I realised delegates have a unique signature to it, so I can't really mix delegated methods (with diff signatures) into a List, or can I?
I did a bit more googling, and found Reactive LINQ, so far, linq looks awesome, but I still don't really get when to use them.
So my question is, how would you implement the Signals concept in C#? Thanks!
Oh did I mention I'm new (1 day old) to C#? I do have a background of various other languages incl Java/C/Python.
Cheers :)
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.
精彩评论