After discovering lambda expressions, and their use as anonymous functions, I've found myself writing a lot of more trivial events such as these:
txtLogin.GotFocus += (o, e) =>
{
txtLogin.Text = string.Empty;
txtLogin.ForeColor = SystemColors.ControlText;
};
txtLogin.LostFocus += (o, e) =>
{
txtLogin.Text = "Login...";
txtLogin.ForeColor = SystemColors.InactiveCaptionText;
};
I've also moved away from event handlers which just call other functions, replacing them with small lambdas which do the same:
backgroundWorker.DoWork += (o, e) => DatabaseLookup.Open(e.Argument as string);
I've found some similar questions addressing performance concerns and pointing out that you can't remove them, but I haven't found any addressing the simple question of is this a good idea?
Is the use of lambdas in such a way considered good form, or do more experience programmers look down on this? Does it hide event handlers in hard-to-find places, or does it do the code a service by reducing the number of trivial event handlers?
It's a perfectly reasonable idea - but in this particular case, I would use an anonymous method instead:
txtLogin.LostFocus += delegate
{
txtLogin.Text = "Login...";
txtLogin.ForeColor = SystemColors.InactiveCaptionText;
};
The benefit is that you don't have to specify the parameters - which makes it clearer that you're not using them. This is the only advantage that anonymous methods have over lambda expressions.
The performance hit is almost always going to be negligible. The inability to remove them afterwards is a very real problem if you do need to be able to remove the handler, but I find that often I don't. (Reactive Extensions has a nice approach to this - when you subscribe to an observable sequence, you're given back an IDisposable which will remove the subscription if you call it. Very neat.)
Actually, it's consider it putting event handlers in easy-to-find places, namely right next to the name of the event it's assigned to.
A lot of the time, you'll see event handlers like:
void Text1_KeyDown(....) {....}
attached to the KeyUp event of txtFirstName, because after using Intellisense to create the handler, someone decided to rename the textbox, and that KeyUp worked better. With the Lambda, the object, the event and the function are all together.
It's a tricky one. I remember reading in Code Complete about how some (smart) people say you should keep the flow of control as simple as possible, with many arguing for single entry and exit points from a method, because not doing so made the program harder to follow.
Lambdas are getting even further away from that, making it very difficult in some cases to follow what's happening, with control leaping around from place to place.
Basically, I think it probably is a bad idea because of this, but it's also powerful and makes life easier. I certainly use them a fair amount. In summary, use with caution!
Related
I have the following code and am wondering how to break it down? It works great but was written by a guru and is over my head. Thank you in advance for any help.
The code basically writes device information sent and received to the GUI. It seems like it has events created based on the device and also invokes GUI stuff.
Why would you need to invoke?
I guess I'm wondering if this is overly complicated or appropriate? What may be a better way to accomplish the same task?
I'm also wondering what the "delegate { };" does?
public event EventHandler CommunicationPerformed = delegate { };
SerialPort _port;
readonly int _delay = 100;
private string ReadAndUpdateStatus()
{
string read = _port.ReadExisting();
CommunicationPerformed?.Invoke(this, new LoaderReadWriteEventArgs(read, LoaderCommunicationDirection.Read));
return read;
}
private void WriteAndUpdateStatus(string data)
{
if (!data.StartsWith("//")) //ignore "Comment" lines but show them on the GUI to read
_port.Write(data);
CommunicationPerformed?.Invoke(this, new LoaderReadWriteEventArgs(data, LoaderCommunicationDirection.Write));
}
public class LoaderReadWriteEventArgs : EventArgs
{
public LoaderCommunicationDirection Direction { get; }
public string Value { get; }
public LoaderReadWriteEventArgs(string value, LoaderCommunicationDirection direction)
{
Value = value;
Direction = direction;
}
}
public enum LoaderCommunicationDirection
{
Read,
Write
}
You asked three questions, and as usual, only one of them got answered. Try to ask only one question in your question.
I'm also wondering what the delegate { } does?
public event EventHandler CommunicationPerformed = delegate { };
As the other answer notes, events are null by default in C#. This technique makes an event handler that does nothing, but is not null.
There are, unfortunately, many syntaxes for an anonymous function in C#. delegate {} means "give me a do-nothing function that matches any non-ref-out formal parameter list that is void returning". That's why people do delegate{}, because it works almost anywhere in a context where an event handler is expected.
I think you need to review this https://learn.microsoft.com/en-us/dotnet/standard/events/.
Why would you need to invoke?
To broadcast to event handlers (any party who registered for this event get notified this way)
I guess I'm wondering if this is overly complicated or appropriate?
*What may be a better way to accomplish the same task?
This is not complicated. This is pretty much as easy as it gets.*
I'm also wondering what the "delegate { };" does?
my two cents.
I dont know which code line you are refering but a delegate is a type that holds a reference to a method. A delegate is declared with a signature that shows the return type and parameters for the methods it references, and can hold references only to methods that match its signature. A delegate is thus equivalent to a type-safe function pointer or a callback. A delegate declaration is sufficient to define a delegate class.
orhtej2 answered your first question quite nicely. Using the explicit Invoke method allows you to leverage the null conditional operator, which reduces the code to fire the event a single line.
As for whether this is overly complicated: No, that's basically how events are done.
What I've sometimes seen (especially in combination with the INotifyPropertyChanged interface in MVVM patterns) are helper methods, which encapsulate the longer, but more obvious pre-C#6 code and let you fire the event with less plumbing.
private void FireCommPerformed(string value, LoaderCommunicationDirection direction)
{
EventHandler handler = CommunicationPerformed;
if (handler != null)
{
handler(this, new LoaderReadWriteEventArgs(value, direction)));
}
}
You could then use it like this:
private string ReadAndUpdateStatus()
{
string read = _port.ReadExisting();
FireCommPerformed(read, LoaderCommunicationDirection.Read);
return read;
}
The Delegate { } is simply an empty delegate, like a null for events. Unless some other method in the code subscribes to the CommunicationPerformed event of this class during runtime, nothing will happen when the event is fired.
Let's focus in on what is exactly happening here. This should help you figure out everything else.
CommunicationPerformed?.Invoke(this, new LoaderReadWriteEventArgs(read, LoaderCommunicationDirection.Read));
This is checking to see if the delegate (event handlers are delegates) (CommunicationPerformed) is null.
Delegates are pointers (but with extra functionality).
If the delegate (pointer) is null, it means that nothing has been assigned to it.
Pointers store memory locations. In this case, it makes a memory reference to the function 'this'. 'This' is a reference to ReadAndUpdateStatus().
So this line basically says: "since the pointer is null, have this pointer reference the ReadAndUpdateStatus() function".
But what about the event args? Well... This is where delegates diverge from pointers.
Delegates don't just safely hold and store memory locations. They also can hold parameters.
You use a class that extends from EventArgs as the way of passing in a list of parameters.
From here, the event handler (event handlers are delegates) CommunicationPerformed will coordinate sending that list of arguments to whatever functions require it.
These functions are called whenever CommunicationPerformed is invoked (e.g. told to run). This is typically indicated with a:
+=CommunicationPerformed(foo,bar)
Now - why would use event handlers (or any delegate - for that matter)?
They're verbose and annoying to read (way more work than writing a simple bool and a trigger function), they don't look like other function, and they're frankly weird - right?
Except that they're really useful. Here's how:
1.) They work a lot like Tasks. You can invoke them in Parallel, in loops, wherever. They keep consistent state. They don't "bleed" and cause bugs.
2.) They're pointers. Guaranteed pass-by-reference. Except, they're magical, and if you stop using the delegate, they won't linger in memory.
3.) They allow you to control state in loops. Sometimes, a bool trigger won't work properly if you're in a really tight loop. You fire an event? Guaranteed behavior that your trigger will only be fired once.
I'm gonna try to answer #1 and #2 (3 is already covered).
#1 - At some point, someone decided that other parts of the program could subscribe to an event that tells them when communication has been performed. Once that decision has been made, it's kind of a "contract". You perform the communication->you fire the event that notifies subscribers that communication has been performed. What those subscribers are doing about that, or why they need to know...Actually not really any of your concern if this class is your focus. In theory, at least. And often that's really practically the case. If your class is doing its job, it's not really your concern who is listening to the events.
#2 - I do think the method of declaring events and event handlers in your code is overly complicated. Plenty of people (and official Microsoft best practices) disagree with me. You can google "why should my event handlers use eventargs" and read plenty on the subject. Or Look here. Another approach is the following:
public event Action<string, LoaderCommunicationDirection> CommunicationPerformed;
void PerformWrite()
{
string myComm = "String I'm sending";
//Line of code that performs communication that writes string here
CommunicationPerformed?.Invoke(myComm, LoaderCommunicationDirection.Write);
}
This is much more succinct than having an entire class that derives from EventArgs. However, it has the very obvious drawback that if you are an event subscriber...you have no idea what string is. Of course, since it's named value in your code...that's not much more helpful. And a comment above the event declaration is just about as useful.
In assigning event handlers to something like a context MenuItem, for instance, there are two acceptable syntaxes:
MenuItem item = new MenuItem("Open Image", btnOpenImage_Click);
...and...
MenuItem item = new MenuItem("Open Image", new EventHandler(btnOpenImage_Click));
I also note that the same appears to apply to this:
listView.ItemClick += listView_ItemClick;
...and...
listView.ItemClick += new ItemClickEventHandler(listView_ItemClick);
Is there any particular advantage for the second (explicit) over the first? Or is this more of a stylistic question?
In C# 1.0 you had no choice but to explicitly define the delegate type and the target.
Since C# 2.0 the compiler allows you to express yourself in a more succinct manner by means of an implicit conversion from a method group to a compatible delegate type. It's really just syntactic sugar.
Sometimes you have no choice but to use the long-winded syntax if the correct overload cannot be resolved from the method group due to an ambiguity.
It's syntax for older version of C# compiler (<=1.1). Not needed anymore. Current compilers are sophisticated enough to get it right.
There's one (little) benefit, sometimes. If you assign event handlers by "+=", the Intellisense autocomplete feature may make writing code a bit faster.
The only time when this is useful is if it would otherwise be ambiguous - for example, if it was MenuItem(string, Delegate) - of if there were multiple equally matching overloads that would match the signature. This also includes var syntax (shown below) and generic type inference (not shown):
EventHandler handler = SomeMethod; // fine
EventHandler handler = new EventHandler(SomeMethod); // fine
var handler = new EventHandler(SomeMethod); // fine
var handler = (EventHandler)SomeMethod; // fine
var handler = SomeMethod; // not fine
In all other cases, it is redundant and is unnecessary in any compiler from 2.0 onwards.
Related to your edit - The adding of handlers isn't really affected by using new or not but there's a slight difference in removing handlers like this
listView.ItemClick -= listView_ItemClick;
and
listView.ItemClick -= new ItemClickEventHandler(listView_ItemClick);
albeit unlikely to affect most scenarios. The first version, without the new keyword, is supposedly more efficient.
There's a detailed explanation in this post but the conclusion is
So both works but which one should we use? If the events are
subscribed/unsubscribed once at the beginning/end like in a typical
WinForm application then it hardly matters. However if this is done
multiple times then the second approach is preferable as it does less
of costly heap allocations and will work faster
(second approach in that post being the one without the new keyword)
Having said that it seems like a micro optimization to me so it's unlikely to be a bottleneck in the majority of cases.
i found this syntax from another article(C# How to stop animated gif from continually looping) but it seems i cant understand it. what is the meaning or purpose of s and e from
System.Drawing.ImageAnimator.Animate(txImage.Image, (s,e) => OnFrameChanged(s,e));
// start
System.Drawing.ImageAnimator.Animate(txImage.Image, (s,e) => OnFrameChanged(s,e));
// stop
System.Drawing.ImageAnimator.StopAnimate(txImage.Image, (s, e) => OnFrameChanged(s, e));
private void OnFrameChanged(object sender, EventArgs e)
{
// frame change
}
or simply can anyone explain this briefly. sorry for being stupid but im really new to programming but i really want to learn thank you
There are three basic ways in which you can write an event handler. Unfortunately the author of that code got it pretty wrong by inappropriately mixing them up. What he should have used is the original C# version 1 way:
ImageAnimator.Animate(txImage.Image, OnFrameChanged);
Which is quite straight-forward and easy to understand. Certainly the syntax you should strongly prefer in this case, it makes it very easy to call the StopAnimate() method. To answer your question, I need to show the other two ways, the ones you should not use. In C# version 2, an anonymous delegate can be used to write the code for the event handler in-place:
ImageAnimator.Animate(txImage.Image, delegate {
// Put the OnFrameChanged code here...
});
In C# version 3, lambda expressions became available to write an event handler in-place:
ImageAnimator.Animate(txImage.Image, (s, e) => {
// Put the OnFrameChanged code here...
});
Which is what you asked about. The (s, e) part of the lambda expression represent the two arguments that are passed to the event handler, s is the sender, e is the EventArgs object. Do note that you don't actually use those two arguments in your OnFrameChange code so the lambda syntax is superfluous, the anonymous delegate works just as well. Albeit that many C# programmers have stopped using them and prefer to use the lambda expression syntax everywhere. Which is fair. Even though you don't use the arguments, you must still write them to convince the compiler that your lambda is a proper substitute for the delegate. Much like you still had to write OnFrameChanged with two arguments to keep the compiler happy.
Understanding lambda expression syntax can be a bit of a speed-bump, any decent introductory book about the C# language will do a better job than I can do to explain it.
Last but not least, you'll find some hackorama code in this answer to show you how to pause an animation in a PictureBox without having to use the ImageAnimator class at all. Albeit with some odds that this just adds more questions :)
Animate and StopAnimate expect "an eventHandler object that specifies the method that is called when the animation frame changes."
You can read this as
System.Drawing.ImageAnimator.Animate(txImage.Image, new EventHandler(this.OnFrameChanged))
I am currently in deep need of logging for an existing application, and can't afford to add the level of logging I expect directly into the code. As a workaround, I'd be happy to have a certain amount of logging done each time an event is fired.
I am considering a solution where I could, at runtime, parse the whole application to wrap all event-to-handler bindings with event-to-wrapper-to-handler; and, ideally, unwrap them at runtime too. In Pseudo-code, this would be:
IDictionary<Event, Action<object, EventArgs>) originalBindings = ...;
public void SetWrapBindings()
{
var allBindingsToReplace = Assembly.GetAssembly().GETALLEVENTS()
.Where(eventInfo => eventInfo.GetOtherMethods().Any());
foreach(var binding in allBindingsToReplace)
{
binding.event -= binding.handler;
binding.event += HandlerWrapper;
originalBindings.Add(binding.event, binding.handler);
}
}
public static void HandlerWrapper(object o, EventArgs e)
{
// Do some logging
try
{
var handler = originalBindings.TryGetValue(/* something */);
handler.Invoke(o, e);
}
// Do more logging
}
In this bunch of pseudo-code there are lots of steps I was not able to write, possibly because I didn't find the correct API use, but maybe also because some operation in that is theoretically impossible (in which case I'd love to know why). These are:
Iterating over all events of the application (this would probably be easy)
Identifying a good key for my IDictionary
At each step, get the relevant information from the context
Of course, binding one extra handler to each existing event (pre/post-executing a routine without really wrapping the handler) would help, but executing the real handler inside a try-catch is a big nice to have.
Any partial answer is still greatly appreciated
If you're looking for non-invasive system-wide logging, you'd be better off using an aspect-oriented programming framework like PostSharp. This page provides a decent jumping off point for what you're looking for.
Edit: To add to this, look at implementing an EventInterceptionAspect if you really do just want to know when any event is raised. Again, the PostSharp blog is a good source of info, and this article shows an implementation of this aspect that does simple stdout logging of adding, removing, and invoking.
When I deal set up events, I usually write as such:
data.event += new data.returndataeventhandler(method);
And have a method as such:
void method(parameter)
{
dosomething();
}
This is when the event returns an object.
I have just been reading through somebody elses code and they have used, what seems to be a much cleaner way, as such:
data.ReturnData += delegate(DataSet returnedDataSet)
{
dataset = returnedDataSet;
};
Is there any downfall to this way?
Thanks.
The one major downfall of using anonymous delegates (or the even-cleaner Lambda as suggested by tster) is that you're not going to be able to unsubscribe it from the event later unless you give it some sort of name.
In most cases, this is "No Big Deal (tm)" because the delegate will go away whenever the event source goes away, but this can be a "Subtle Mistake (tm)" if you're subscribing to static events or events on long-lived objects (e.g., the WPF Dispatcher object).
In your case, this doesn't look like a problem at all, so I'd definitely recommend going with tster's recommendation (assuming you're using an appropriately recent version of .Net):
data.ReturnData += returnedDataSet => dataset = returnedDataSet;
(The compiler can infer the type of returnedDataSet from the EventHandler type of ReturnData.)
The primary downfall of using anonymous delegates is that they are not reusable. Other than that there is typically no difference between defining a delegate and then using it elsewhere in your code versus using an anonymous delegate.
One down fall is that it will not appear in your method drop down list. If you do it inline, it should only be simple, nothing overly complex.
Like said by others, the most obvious is not reusable.
Other points:
readability in particular if you have large method body
because .NET generate a random name for anonymous method (not very meaningful or readable) if you use reflection type technology or profiler, it may complicate traceability.
The only downfall is that if you have more than one event it's easier to point it to a method. If you had to attach events in different blocks to the same handler, you would have to store your delegate somewhere so that both blocks could "see" it.
Even cleaner:
data.ReturnData += returnedDataSet => dataset = returnedDataSet;
Nope its just anonymous method thats all.
You can read more about anonymous methods here.
Aside from the other answers of reusablity/Intellisense, I believe the only downfall is if you need to remove the handler later. With a delegate/lamba you cannot easily remove your handler if it no longer needs to be called.