Can a lambda allow another object to inject an action - c#

I want a WinForm to register the OnLoad event with another object - something like:
SomeObject.RegisterEvent(action => this.OnLoad += (o,e) => action(o,e));
Is this possible? I don't mind creating delegates or expressions for 'helpers' on the 'SomeObject' side to do this, but I'm trying to figure out what my method signature would even look like for the RegisterEvent(...).

The RegisterEvent method would need to look like this:
void RegisterEvent(Action<EventHandler> addEventHandler)
{
addEventHandler((sender, e) =>
{
// loaded
});
}
Usage:
someObject.RegisterEvent(handler => { this.OnLoad += handler; });

SomeObject.RegisterEvent(action => { this.OnLoad += (o,e) => {action(o,e);}; });

If you really need to have something like that (always a good question, usually things like this are a tell signs of something a bit odd-ish about the design, but doesn't have to be),
I'd say you should look at The Reactive Extensions (Rx)....
They provide the ease with dealing and firing off your own 'events' more or less like properties or methods (and w/o the typical pain of delegates, add/subscribe or private limitations etc., over simplified a bit).
...and this could look like...
someObjectInstance.MyEvent.Subscribe(d=>
{
// ... your lambda more or less
});
...and in the class there is if simplified just one Subject<MyEventData> _myEvent; and _myEvent.OnNext(data) (goes inside the method you want to rise from) + the property to expose that field (IObservable<MyEventData> MyEvent {get{return _myEvent;}}).
which is what you want really.
You can install them from NuGet and use in minutes. Though there is a learning curve for more tricky cases.
Plus you get the benefit of combining events in the future and lot more.
(not 'one of them', just a very good new piece of technology)

Related

Getting instance of delegate from inside itself C#

I am working with a WCF service, calls to the service are invoked using an async method. As I am working with Xamarin studio the WCF proxy must be created using the silverlight tools (slsvcutil.exe) and as such this seems to be the only way to achieve what I am doing.
To make a call to the service I must make a call like so:
Soap.client.DoActionCompleted += Soap_client_DoActionCompleted;
Soap.client.DoActionAsync(parameter);
And then declare the delegate for DoActionCompleted like so:
void Soap_client_DoActionCompleted(object sender, DoActionCompletedEventArgs e)
{
Soap.client.DoActionCompleted -= Soap_client_DoActionCompleted;
// Do stuff
}
I have to remove Soap_client_DoActionCompleted after the call to prevent it from stacking further calls on it later.
The problem is I have many calls like this in my code, and it is beginning to get very messy and hard to follow the logic when writing the code. I would much prefer to be able to declare the code inline so it's much easier to follow, something like this:
Soap.client.DoActionCompleted += (sender, e) =>
{
Soap.client.DoActionCompleted -= x;
// Do stuff
}
Soap.client.DoActionAsync(parameter);
In the above snippet, I'd like to be able to pass the delegate that it is inside to remove it then and there, but the problem is I have no idea if this is even possible.
While I know there are almost certainly better ways of doing the above, I'm a little trapped by the fact that I am required to use slsvcutil.exe to generate the proxy for the service, and writing the proxy manually isn't an option as the service gets regular updates.
It's kind of possible if you assign the lambda expression to a delegate variable first. It just won't be as nice as what you're hoping for.
And even then, to avoid a use of unassigned local variable compiler error, you have to first initialize the delegate variable to null before you can assign the lambda expression that will have a reference to itself.
So, using your example, it would look like this (I'm assuming the type of DoActionCompleted is EventHandler. Simply adjust if I'm wrong):
EventHandler eventHandler = null;
eventHandler = (sender, e) =>
{
Soap.client.DoActionCompleted -= eventHandler;
// do stuff
};
Soap.client.DoActionCompleted += eventHandler;
Soap.client.DoActionAsync(parameter);
It's up to you to decide if it's worth it for you to use this pattern.

Is it possible to target an EventHandler in a lambda expression?

For a simple example, if I had some sort of button UI class, could I write a function that takes an expression that points to its Click event handler:
SomeMethod<SomeButtonClass>(button => button.Click);
I'm trying to eliminate some magic strings currently being used for a system to make events awaitable. The code in question is derived from a blog post by Frank Krueger (a worthwhile read, if you want some background).
public static Task<TEventArgs> GetEventAsync<TEventArgs>(this object eventSource, string eventName) where TEventArgs : EventArgs {
//...
Type type = eventSource.GetType();
EventInfo ev = type.GetEvent(eventName);
//...
}
While the specifics inside probably aren't important, the full method allows you to use an Event triggering as the completion source for a Task, making it easier to manage with await. For some class that raises an event, you can tie into a Task based on that event with a simple call.
Task<EventArgs> eventTask = someEventCausingObject.GetEventAsync<EventArgs>("SomeEventHandler");
// traditionally used as someEventCausingObject.SomeEventHandler += ...;
await eventTask;
// Proceed back here when SomeEventHandler event is raised.
I have been using this happily for a couple projects, but it has its drawbacks, one of the biggest being the use of hard-coded event name strings. This makes event name changes turn into runtime exceptions, and determining usage of the event is difficult.
I started trying to make a version that would allow the EventHandler to be passed in as part of an Expression with the goal of something like this:
await someEventCausingObject.GetEventAsync<EventCausingClass, EventArgs>(x => x.SomeEventHandler);
...with the corresponding method signature...
public static Task<TEventArgs> GetEventAsync<TSource, TEventArgs>(this TSource eventSource, Expression<Func<TSource, EventHandler>> eventHandlerExpression) where TEventArgs : EventArgs {
//...
}
Unfortunately, the lambda expression in the calling code causes a compile error:
Error CS0070: The event `SomeEventHandler' can only appear on the left hand side of += or -= when used outside of the type `EventCausingClass'.
This makes some sense given how event handlers are typically used, but I was hoping to find a better solution going forward than the pre-specified string name. It seems searches for combinations of "expression" and "eventhandler" all tend to be polluted with people describing lambda expressions for beginning += event handler assignment. I'm hoping I am missing something obvious here.
No, it is not possible to target an event. Basically event is not a real type member, but just C# syntax which produces add_EventName and remove_EventName methods pair.
You could try refer to these internal methods name, but it's not possible in C# - http://msdn.microsoft.com/en-us/library/z47a7kdw.aspx
There are many similar questions in SO, with the same answer NO - like this one from Jon Skeet https://stackoverflow.com/a/4756021/2170171
If you're real crazy, you can try something like
private static void Subscribe(Action addHandler)
{
var IL = addHandler.Method.GetMethodBody().GetILAsByteArray();
// Magic here, in which we understand ClassName and EventName
???
}
with usage like
Subscribe(() => new Button().Click += null);
You could try using Cecil http://www.mono-project.com/Cecil for analyzing IL, or implement your own logic as it should not be too hard for predictable line of code.
I don't think that it is good solution though, as it just replaces one headache (proper event naming) with another one (proper Subscribe calling). Though, it will help with rename stuff.

How to automatically generating an extension method library of WPF Event -> IObservable

I almost exclusively use Reactive Extensions in my C# WPF apps these days. Adding and removing event handlers is an anti pattern and I'm completely jealous of the fact that F# events implement IObservable.
To help C# developers the RX folks provide the below method ( and some others of varying type safeness )
public static
IObservable<EventPattern<TEventArgs>>
FromEventPattern<TDelegate, TEventArgs>
( Action<TDelegate> addHandler
, Action<TDelegate> removeHandler
)
where TEventArgs : EventArgs
http://msdn.microsoft.com/en-us/library/hh211731(v=vs.103).aspx
I would use it like so
var movingEvents = Observable.FromEventPattern<MouseEventHandler,
MouseEventArgs>(h => this.MouseMove += h, h => this.MouseMove -= h);
However this is tedious. What I'd like to be able to do is
var movingEvents = h.MouseMoveObserver();
and be done with it. Such an extension method would look like
IObservable<MouseEventArgs> MouseMoveObserver(this Canvas This){
return Observable.FromEventPattern<MouseEventHandler,
MouseEventArgs>(h => This.MouseMove += h, h => This.MouseMove -= h);
}
It's not rocket science and I've been considering setting up a library where I add these extension methods one at a time as I need them. However I am sure some smart cookie could write a T4 template that processes all the controls in the WPF library via reflection and generates all the extension methods I would ever need. My question is ...
Has anybody written such a code generator to map events to observables as above and if not would someone have any suggestions on how to do this? I'm not so good with regards to .Net reflection but some seed code might get me started.
To get all the types deriving from FrameworkElement, you could use
var typesToDo = from t in Assembly.GetAssembly(typeof(FrameworkElement)).GetTypes()
where t.IsSubclassOf(typeof(FrameworkElement))
&& t.IsPublic
&& t.GetEvents().Any()
select t;
and then you can use type.GetEvents() to get the events of each type. The EventInfo you get back will let you look at things like name, type, arguments etc.
You need to do a bit of extra work to cope with generic events, but it's not a huge amount.
I've put an example program up on GitHub along with an example of the output.
There is a risk that some of the output doesn't work properly, I haven't tried them all :) I did make sure they all build, and that at least some of them work correctly.

why do we need delegates [duplicate]

I'm looking to implement the Observer pattern in VB.NET or C# or some other first-class .NET language. I've heard that delegates can be used for this, but can't figure out why they would be preferred over plain old interfaces implemented on observers. So,
Why should I use delegates instead of defining my own interfaces and passing around references to objects implementing them?
Why might I want to avoid using delegates, and go with good ol'-fashioned interfaces?
When you can directly call a method, you don't need a delegate.
A delegate is useful when the code calling the method doesn't know/care what the method it's calling is -- for example, you might invoke a long-running task and pass it a delegate to a callback method that the task can use to send notifications about its status.
Here is a (very silly) code sample:
enum TaskStatus
{
Started,
StillProcessing,
Finished
}
delegate void CallbackDelegate(Task t, TaskStatus status);
class Task
{
public void Start(CallbackDelegate callback)
{
callback(this, TaskStatus.Started);
// calculate PI to 1 billion digits
for (...)
{
callback(this, TaskStatus.StillProcessing);
}
callback(this, TaskStatus.Finished);
}
}
class Program
{
static void Main(string[] args)
{
Task t = new Task();
t.Start(new CallbackDelegate(MyCallbackMethod));
}
static void MyCallbackMethod(Task t, TaskStatus status)
{
Console.WriteLine("The task status is {0}", status);
}
}
As you can see, the Task class doesn't know or care that -- in this case -- the delegate is to a method that prints the status of the task to the console. The method could equally well send the status over a network connection to another computer. Etc.
You're an O/S, and I'm an application. I want to tell you to call one of my methods when you detect something happening. To do that, I pass you a delegate to the method of mine which I want you to call. I don't call that method of mine myself, because I want you to call it when you detect the something. You don't call my method directly because you don't know (at your compile-time) that the method exists (I wasn't even written when you were built); instead, you call whichever method is specified by the delegate which you receive at run-time.
Well technically, you don't have to use delegates (except when using event handlers, then it's required). You can get by without them. Really, they are just another tool in the tool box.
The first thing that comes to mind about using them is Inversion Of Control. Any time you want to control how a function behaves from outside of it, the easiest way to do it is to place a delegate as a parameter, and have it execute the delegate.
You're not thinking like a programmer.
The question is, Why would you call a function directly when you could call a delegate?
A famous aphorism of David Wheeler
goes: All problems in computer science
can be solved by another level of
indirection.
I'm being a bit tongue-in-cheek. Obviously, you will call functions directly most of the time, especially within a module. But delegates are useful when a function needs to be invoked in a context where the containing object is not available (or relevant), such as event callbacks.
There are two places that you could use delegates in the Observer pattern. Since I am not sure which one you are referring to, I will try to answer both.
The first is to use delegates in the subject instead of a list of IObservers. This approach seems a lot cleaner at handling multicasting since you basically have
private delegate void UpdateHandler(string message);
private UpdateHandler Update;
public void Register(IObserver observer)
{
Update+=observer.Update;
}
public void Unregister(IObserver observer)
{
Update-=observer.Update;
}
public void Notify(string message)
{
Update(message);
}
instead of
public Subject()
{
observers = new List<IObserver>();
}
public void Register(IObserver observer)
{
observers.Add(observer);
}
public void Unregister(IObserver observer)
{
observers.Remove(observer);
}
public void Notify(string message)
{
// call update method for every observer
foreach (IObserver observer in observers)
{
observer.Update(message);
}
}
Unless you need to do something special and require a reference to the entire IObserver object, I would think the delegates would be cleaner.
The second case is to use pass delegates instead of IObervers for example
public delegate void UpdateHandler(string message);
private UpdateHandler Update;
public void Register(UpdateHandler observerRoutine)
{
Update+=observerRoutine;
}
public void Unregister(UpdateHandler observerRoutine)
{
Update-=observerRoutine;
}
public void Notify(string message)
{
Update(message);
}
With this, Observers don't need to implement an interface. You could even pass in a lambda expression. This changes in the level of control is pretty much the difference. Whether this is good or bad is up to you.
A delegate is, in effect, passing around a reference to a method, not an object... An Interface is a reference to a subset of the methods implemented by an object...
If, in some component of your application, you need access to more than one method of an object, then define an interface representing that subset of the objects' methods, and assign and implement that interface on all classes you might need to pass to this component... Then pass the instances of these classes by that interface instead of by their concrete class..
If, otoh, in some method, or component, all you need is one of several methods, which can be in any number of different classes, but all have the same signature, then you need to use a delegate.
I'm repeating an answer I gave to this question.
I've always like the Radio Station metaphor.
When a radio station wants to broadcast something, it just sends it out. It doesn't need to know if there is actually anybody out there listening. Your radio is able to register itself with the radio station (by tuning in with the dial), and all radio station broadcasts (events in our little metaphor) are received by the radio who translates them into sound.
Without this registration (or event) mechanism. The radio station would have to contact each and every radio in turn and ask if it wanted the broadcast, if your radio said yes, then send the signal to it directly.
Your code may follow a very similar paradigm, where one class performs an action, but that class may not know, or may not want to know who will care about, or act on that action taking place. So it provides a way for any object to register or unregister itself for notification that the action has taken place.
Delegates are strong typing for function/method interfaces.
If your language takes the position that there should be strong typing, and that it has first-class functions (both of which C# does), then it would be inconsistent to not have delegates.
Consider any method that takes a delegate. If you didn't have a delegate, how would you pass something to it? And how would the the callee have any guarantees about its type?
I've heard some "events evangelists" talk about this and they say that as more decoupled events are, the better it is.
Preferably, the event source should never know about the event listeners and the event listener should never care about who originated the event. This is not how things are today because in the event listener you normally receive the source object of the event.
With this said, delegates are the perfect tool for this job. They allow decoupling between event source and event observer because the event source doesn't need to keep a list of all observer objects. It only keeps a list of "function pointers" (delegates) of the observers.
Because of this, I think this is a great advantage over Interfaces.
Look at it the other way. What advantage would using a custom interface have over using the standard way that is supported by the language in both syntax and library?
Granted, there are cases where it a custom-tailored solution might have advantages, and in such cases you should use it. In all other cases, use the most canonical solution available. It's less work, more intuitive (because it's what users expect), has more support from tools (including the IDE) and chances are, the compiler treats them differently, resulting in more efficient code.
Don't reinvent the wheel (unless the current version is broken).
Actually there was an interesting back-and-forth between Sun and Microsoft about delegates. While Sun made a fairly strong stance against delegates, I feel that Microsoft made an even stronger point for using delegates. Here are the posts:
http://java.sun.com/docs/white/delegates.html
http://msdn.microsoft.com/en-us/vjsharp/bb188664.aspx
I think you'll find these interesting reading...
i think it is more related to syntatic sugar and a way to organize your code, a good use would be to handle several methods related to a common context which ones belong to a object or a static class.
it is not that you are forced to use them, you can programme sth with and without them, but maybe using them or not might affect how organized, readable and why not cool the code would be, maybe bum some lines in your code.
Every example given here is a good one where you could implement them, as someone said it, is just another feature in the language you can play with.
greetings
Here is something that i can write down as a reason of using delegate.
The following code is written in C# And please follow the comments.
public delegate string TestDelegate();
protected void Page_Load(object sender, EventArgs e)
{
TestDelegate TD1 = new TestDelegate(DiaplayMethodD1);
TestDelegate TD2 = new TestDelegate(DiaplayMethodD2);
TD2 = TD1 + TD2; // Make TD2 as multi-cast delegate
lblDisplay.Text = TD1(); // invoke delegate
lblAnotherDisplay.Text = TD2();
// Note: Using a delegate allows the programmer to encapsulate a reference
// to a method inside a delegate object. Its like the function pointer
// in C or C++.
}
//the Signature has to be same.
public string DiaplayMethodD1()
{
//lblDisplay.Text = "Multi-Cast Delegate on EXECUTION"; // Enable on multi-cast
return "This is returned from the first method of delegate explanation";
}
// The Method can be static also
public static string DiaplayMethodD2()
{
return " Extra words from second method";
}
Best Regards,
Pritom Nandy,
Bangladesh
Here is an example that might help.
There is an application that uses a large set of data. A feature is needed that allows the data to be filtered. 6 different filters can be specified.
The immediate thought is to create 6 different methods that each return the data filtered. For example
public Data FilterByAge(int age)
public Data FilterBySize(int size)
.... and so on.
This is fine but is a very limited and produces rubbish code because it's closed for expansion.
A better way is to have a single Filter method and to pass information on how the data should be filtered. This is where a delegate can be used. The delegate is a function that can be applied to the data in order to filter it.
public Data Filter(Action filter)
then the code to use this becomes
Filter(data => data.age > 30);
Filter(data => data.size = 19);
The code data => blah blah becomes a delegate. The code becomes much more flexible and remains open.

C# Custom Events assigning to different delegates based on parameters

I'm trying to use events to use the nice += -= syntax.
Here is my problem:
I have a lot of different events, so instead of creating many events, I would like to use only one,
where the registrant additionally supplies an additional parameter (string[]) detailing which (sub)events one wants to listen to.
The is basically what I'm doing now:
public delegate void dMethod(int index);
private Dictionary<string, dMethod> events;
public void RegisterEvents(dMethod m, string[] subEvents){
foreach(string subEvent : subEvents){
events[subEvent] += m;
}
}
Instead I would like to do something like this:
public delegate void dMethod(int index);
private Dictionary<string, dMethod> events;
public event dMethod Events(string[] subEvents) {
add {
foreach(string subEvent : subEvents){
events[subEvent] += value;
}
}
remove {
foreach(string subEvent : subEvents){
events[subEvent] -= value;
}
}
}
Is something like passing additional parameters upon event registration somehow possible?
The simplest solution I thought of was to use the delegates return value (changing it to string[]).
But that is just hacky and not worth it.
If it is not possible, is there some way I can define += -= myself?
Why exactly don't you want to use one event per... event ?
What you're trying to do would add an indirection step (which will hurt performance), and more importantly deny you the advantages of compile-time error detection and code analysis (what if your string doesn't match an existing event? wouldn't it be nice to find out about the error at compile-time rather than runtime? What about the "find all references" tool?)
If all of your events are really separate events (which have nothing to do with one another), you should create those events. Creating one single event for all kinds of things would be a bit like creating one big sql table with 255 Columns instead of a true database design.
On the other hand, you may be able to find an abstraction of all those events, and add an argument to the event handler (not to the subscription logic) specifying what sub-event has been called. See IBindingList for an example of this technique. Note the use of an enumeration instead of strings to avoid spelling mistakes.
Could you give us some example (business-wise) of the events you're working on ?
The simplest solution I thought of was
to use the delegates return value
(changing it to string[]).
I dont quite understand what you mean by this. Would the event handler return the events it wants to handle?
I don't think that what you want to do is an option. It may be possible (if you abandon the .Net event system) to use the += syntax by creating a custom class and some implicit conversion operators to produce code something like:
SomePropertyThatIsntARealEvent[new string[] {"event1", "event2"}] += someDelegate
// or even
SomePropertyThatIsntARealEvent["event1"]["event2"] += someDelegate
Note that, if it's even doable, it would be messy and hacky and not really worth it anyways. Also, unfortunately, you can't use params for indexers.
I would recommend that you just stick with the un-pretty way.
This isn't an answer to your main question, but for ease of use I'd add the "params" keyword to your method, like so:
public void RegisterEvents(dMethod m, params string[] subEvents)
This will let you call the method like this:
RegisterEvents(m, "Bob", "Doug", "Susie");
instead of:
RegisterEvents(m, new string[] { "Bob", "Doug", "Susie" });

Categories