Since we have multicast delegates, why do we need events? [duplicate] - c#

This question already has answers here:
Difference between events and delegates and its respective applications [closed]
(10 answers)
Closed 3 years ago.
I was asked this question in an interview, and either I'm suffering from brain-lock or just plain dumb, but I didn't have an answer.

Couple of reasons why we need events:
Restricting scope, you do not want to expose your events, like you can for your delegates.
You can have events as fields in your interfaces and not delegates
Example below:
Class Printer
{
public event EventHandler Print;
public void Start()
{
OnPrint();
}
protected virtual void OnPrint()
{
Print?.Invoke(this,EventArgs.Empty);
}
}
class Program
{
static void Main(string[] args)
{
//When Print is an EventHander
var printer = new Printer();
printer.Print += PrintEvent;
printer.Start();
//If Print was a delegate this is possible, else you get compile time errors
printer.Print(null,null); // Events will not allow to have a direct invoke
printer.Print = null; //You cannot assign a null to an Event Handler
}
private static void PrintEvent(object sender, EventArgs e)
{
System.Console.WriteLine("Printing event");
}
}

Related

What is the difference between these two event declarations? [duplicate]

This question already has answers here:
What are the differences between delegates and events?
(11 answers)
Closed 6 years ago.
I have two events in a class
public event AcquiredDataEvent OnNewAcquiredData;
public delegate void AcquiredDataEvent(int[] newData);
public ScanStartedEvent ScanStarted;
public delegate void ScanStartedEvent();
I just realized that ScanStarted does not have the keyword event before it. Most likely the result of a typo by me, though it still works as expected.
What is the difference between the two events if any?
ScanStarted is not event. It's just a field of delegate type.
It can be invoked outside of class where field is declated.
It does not provide add/remove methods (that is what event is, like property is a pair of get/set methods) for attaching/removing event handlers - you can simply assign new delegate to ScanStarted field.
BTW Just like you can have property without backing field
public int Value
{
get { return 42; }
set { Console.WriteLine($"Haha, keep {value} for yourself"); }
}
You can have event without delegate field under the hood
public event AcquiredDataEvent OnNewAcquiredData
{
add { Console.WriteLine("Trying to attach some handlers?"); }
remove { Console.WriteLine("Haha, you should attach something first!"); }
}

Get delegate handler from event [duplicate]

This question already has answers here:
Is it possible to "steal" an event handler from one control and give it to another?
(4 answers)
Closed 7 years ago.
I am trying to get the event handler without doing any changes in MyControl class. I tried to use reflection but I am not able to get the handler.
Following is a code sample.
Thanks
public class MyControl : Control
{
public void Register()
{
SizeChanged += MyControl_SizeChanged;
}
void MyControl_SizeChanged(object sender, EventArgs e)
{
// Do something
}
}
//[TestFixture]
public class MyControlTest
{
// [Test]
public void RegisterTest()
{
var control = new MyControl();
control.Register();
var eventInfo = control.GetType().GetEvent("SizeChanged", BindingFlags.Public | BindingFlags.Instance);
// Need to get the handler (delegate) and GetInvocationList().Count
EventHandler handler = ...;
var count = handler.GetInvocationList().Count();
Assert.That(count, IsolationLevel.EqualTo(1));
}
}
Events don't actually have handlers; an event is just a pair of specially-named add & remove methods.
For more information, see my blog.
How the event stores its handlers is an implementation detail; WinForms controls use an EventHandlerList.
You can see this in the source.
That's probably because of it's protection level which is currently private as can be seen from your posted code
void MyControl_SizeChanged(object sender, EventArgs e)
{
// Do something
}

updating GUI status bar from DLL [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have one application developed in C# and one C# dll which i am using for serial communication.
after every 10 seconds i want to update the GUI from dll and want to send status message from dll to the Main program.
callback maybe the option for this. but not able to write it correctly.
It will be great if someone can give me proper syntax.
So this is just an example. First, the code from your DLL which exposes an event.
class MyWorkerClass
{
public event EventHandler<System.ComponentModel.ProgressChangedEventArgs> Changed;
void OnChanged(ProgressChangedEventArgs args)
{
if (Changed != null) Changed(this, args);
}
public void DoWork(object state)
{
// do your work
OnChanged(new ProgressChangedEventArgs(50, state); // use percentage
}
}
And the code in your GUI.
public class MyGUI
{
readonly MyWorkerClass worker;
public MyGUI()
{
this.worker = new MyWorkerClass();
this.worker.Changed += OnWorkerChanged;
}
public void OnWorkerChanged(object sender, ProgressChangedEventArgs args)
{
// ToDo: use args.ProgressPercentage to update a GUI element (example: ProgressBar)
// Remark: make sure you are in the GUI thread. Use this.InvokeRequired to check
}
}
Use a delegate:
public class SerialReader
{
public Action<string> Callback;
public void Read()
{
if (Callback != null)
Callback("Here is a message for the status bar");
}
}
Which the GUI class registers for:
public class GuiClass
{
public void foo() {
var reader = new SerialReader();
reader.Callback = UpdateStatusBar;
}
public void UpdateStatusBar(string message) {
statusBar.Text = message;
}
}
Make sure the Callback is set somewhere in your GUI code:
reader.Callback = UpdateStatusBar;

Use of the event keyword in c#

I was wondering what the exact use of events is in c#. I am still in the process of learning c# so I maybe missing something but is it possible to just use delegates.
In this example I wrote a class with a method that counts from 0 to 2^64 and every time it reaches a multiple of a thousand raises an event. Here is the code:
namespace EventDelegate
{
class Program
{
static void Main(string[] args)
{
EventRaiserClass _eventraiser = new EventRaiserClass();
_eventraiser.handler = SomeEventHandler;
_eventraiser.handler += AnotherEventHandler;
_eventraiser.Loop();
Console.Read();
}
static void SomeEventHandler(object sender, EventArgs args)
{
Console.WriteLine("Event raised");
}
static void AnotherEventHandler(object sendr, EventArgs args)
{
Console.WriteLine("Event raised (Another handler)");
}
}
public delegate void Handler(object sender, EventArgs args);
class EventRaiserClass
{
public Handler handler;
public void Loop()
{
for (long i = 0; i < Int64.MaxValue; i++)
{
if ((i % 1000) == 0)
{
EventArgs args = new EventArgs();
RaiseEvent(args);
System.Threading.Thread.Sleep(1000);
}
}
}
private void RaiseEvent(EventArgs args)
{
if (handler != null)
handler(this, args);
}
}
}
What would the difference have been if I had declared the handler delegate variable to be an event like this public event Handler handler.
Sorry if I am been a bit vague or missing something obvious, but I am just wondering if something else happens behind the scenes when using event rather just using delegates or if it's just for readability purposes.
Events and delegates are similar, but events are more restricted, for good reasons.
In your code, you could do all kinds of things with _eventraiser.handler from the outside. You aren't supposed to do most of those things though.
Consider this line:
_eventraiser.handler = SomeEventHandler;
If you use delegates, you would have to check every time you try to attach an event handler if the delegate is null, and then initialize it with =, and if it is not null, you just have to add handlers with +=. If you forget an initialization, you get a null reference exception, if you put in one too many, you will overwrite all the previous things.
If you use events instead of delegates in this example, you don't have to do any of this, and, in fact, you can't even do it. With delegates you could even take it and then pass it around to some other classes, which could potentially be very dangerous.
The same goes for Invoke, and all the other things you can do with a delegate: They aren't there for events. The only things you can do with an event from an outside class is += and -=, that's it. You can view them as delegates with a special public interface with complicated getters and setters.
(Events also have a special add and remove syntax, but that's a rather uncommonly used feature)

How I can get the calling methods in C# [duplicate]

This question already has answers here:
How can I find the method that called the current method?
(17 answers)
Closed 9 years ago.
Possible Duplicate:
How can I find the method that called the current method?
I need a way to know the name of calling methods in C#.
For instance:
private void doSomething()
{
// I need to know who is calling me? (method1 or method2).
// do something pursuant to who is calling you?
}
private void method1()
{
doSomething();
}
private void method2()
{
doSomething();
}
from http://www.csharp-examples.net/reflection-calling-method-name/
using System.Diagnostics;
// get call stack
StackTrace stackTrace = new StackTrace();
// get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
You almost certainly don't want to do this. A caller should never know who is calling it. Instead, the difference between the two callers should be abstracted into a parameter, and passed into the method being called:
private void doSomething(bool doItThisWay)
{
if (doItThisWay)
{
// Do it one way
}
else
{
// Do it the other way
}
}
private void method1()
{
doSomething(true);
}
private void method2()
{
doSomething(false);
}
This way, if you add a method3, it can either doSomething one way or the other, and doSomething won't care.

Categories