Difference between wiring events with and without new
I did this
static void Hook1()
{
someEvent += new EventHandler( Program_someEvent );
}
static void Hook2()
{
someEvent += Program_someEvent;
}
And then ran ildasm over the code.
The generated MSIL was exactly the same.
So to answer your question, yes they are the same thing.
The compiler is just inferring that you want someEvent += new EventHandler( Program_someEvent );
-- You can see it creating the new EventHandler
object in both cases in the MSIL
Difference between wiring events using new EventHandlerT and not using new EventHandlerT?
Basically, one is shorter than the other. It's just synctactic sugar.
The "correct" syntax is the first one, as ProgresChanged is an EventHandler event, so for you to assign a actual handler to it, you need to create a new EventHandler object, whose constructor takes as a parameter the name of a method with the required signature.
However, if you just specify the name of the method (second syntax), an instance of the eventHandler class is created implicitly, and that instance is assigned to the ProgressChanged event.
I prefer using the second method because it's shorter, and does not lose any information. There are not much contexts where you could mistake a += methodName
construct for something else.
What is the difference between Events with Delegate Handlers and those without?
No difference. Omitting the delegate instantiation is just syntax candy; the C# compiler will generate the delegate instantiation for you under the hood.
C#: Difference between ' += anEvent' and ' += new EventHandler(anEvent)'
There is no difference. In your first example, the compiler will automatically infer the delegate you would like to instantiate. In the second example, you explicitly define the delegate.
Delegate inference was added in C# 2.0. So for C# 1.0 projects, second example was your only option. For 2.0 projects, the first example using inference is what I would prefer to use and see in the codebase - since it is more concise.
Wiring and unwiring events in C# with arguments
The problem is that you haven't register mysys_ValueChanged
. You registered an anonymous method.
You have to change your code to:
public void GetVoltage(Object objName, Object objCcaVar)
{
DynamicSystemVariable mysys = new DynamicSystemVariable("VTS::M9_Ch3", "AvgVoltage");
mysys.ValueChanged += this.OnEvent;
}
private void OnEvent(object sender, EventArgs e)
{
mysys_ValueChanged(sender, e, "");
}
void mysys_ValueChanged(object sender, EventArgs e,String name)
{
DynamicSystemVariable mysys = (DynamicSystemVariable)sender;
Output.WriteLine(mysys.GetValue().ToString());
Output.WriteLine("System Variable Changed");
if (_unwireEvent)
mysys.ValueChanged -= OnEvent; // Unregister what you've registered.
}
EDIT
Having new input it could be solved that way:
public void GetVoltage(Object objName, Object objCcaVar)
{
DynamicSystemVariable mysys = new DynamicSystemVariable("VTS::M9_Ch3", "AvgVoltage");
EventHandler<EventArgs> handler = null;
handler = (s, e) => mysys_ValueChanged(s, e, "", handler);
mysys.ValueChanged += handler;
}
void mysys_ValueChanged(object sender, EventArgs e, String name, EventHandler<EventArgs> handler)
{
DynamicSystemVariable mysys = (DynamicSystemVariable)sender;
Output.WriteLine(mysys.GetValue().ToString());
Output.WriteLine("System Variable Changed");
if (_unwireEvent)
mysys.ValueChanged -= handler; // Unregister what you've registered.
}
I haven't tried it but I think this could work - but in my opinion it's hacked.
+= new EventHandler(Method) vs += Method
Since there seemed to be some dispute over my original answer, I decided to do a few tests, including looking at the generated code and monitoring the performance.
First of all, here's our test bed, a class with a delegate and another class to consume it:
class EventProducer
{
public void Raise()
{
var handler = EventRaised;
if (handler != null)
handler(this, EventArgs.Empty);
}
public event EventHandler EventRaised;
}
class Counter
{
long count = 0;
EventProducer producer = new EventProducer();
public void Count()
{
producer.EventRaised += CountEvent;
producer.Raise();
producer.EventRaised -= CountEvent;
}
public void CountWithNew()
{
producer.EventRaised += new EventHandler(CountEvent);
producer.Raise();
producer.EventRaised -= new EventHandler(CountEvent);
}
private void CountEvent(object sender, EventArgs e)
{
count++;
}
}
First thing to do is look at the generated IL:
.method public hidebysig instance void Count() cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: ldfld class DelegateTest.Program/EventProducer DelegateTest.Program/Counter::producer
L_0006: ldarg.0
L_0007: ldftn instance void DelegateTest.Program/Counter::CountEvent(object, class [mscorlib]System.EventArgs)
L_000d: newobj instance void [mscorlib]System.EventHandler::.ctor(object, native int)
L_0012: callvirt instance void DelegateTest.Program/EventProducer::add_EventRaised(class [mscorlib]System.EventHandler)
L_0017: ldarg.0
L_0018: ldfld class DelegateTest.Program/EventProducer DelegateTest.Program/Counter::producer
L_001d: callvirt instance void DelegateTest.Program/EventProducer::Raise()
L_0022: ldarg.0
L_0023: ldfld class DelegateTest.Program/EventProducer DelegateTest.Program/Counter::producer
L_0028: ldarg.0
L_0029: ldftn instance void DelegateTest.Program/Counter::CountEvent(object, class [mscorlib]System.EventArgs)
L_002f: newobj instance void [mscorlib]System.EventHandler::.ctor(object, native int)
L_0034: callvirt instance void DelegateTest.Program/EventProducer::remove_EventRaised(class [mscorlib]System.EventHandler)
L_0039: ret
}
.method public hidebysig instance void CountWithNew() cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: ldfld class DelegateTest.Program/EventProducer DelegateTest.Program/Counter::producer
L_0006: ldarg.0
L_0007: ldftn instance void DelegateTest.Program/Counter::CountEvent(object, class [mscorlib]System.EventArgs)
L_000d: newobj instance void [mscorlib]System.EventHandler::.ctor(object, native int)
L_0012: callvirt instance void DelegateTest.Program/EventProducer::add_EventRaised(class [mscorlib]System.EventHandler)
L_0017: ldarg.0
L_0018: ldfld class DelegateTest.Program/EventProducer DelegateTest.Program/Counter::producer
L_001d: callvirt instance void DelegateTest.Program/EventProducer::Raise()
L_0022: ldarg.0
L_0023: ldfld class DelegateTest.Program/EventProducer DelegateTest.Program/Counter::producer
L_0028: ldarg.0
L_0029: ldftn instance void DelegateTest.Program/Counter::CountEvent(object, class [mscorlib]System.EventArgs)
L_002f: newobj instance void [mscorlib]System.EventHandler::.ctor(object, native int)
L_0034: callvirt instance void DelegateTest.Program/EventProducer::remove_EventRaised(class [mscorlib]System.EventHandler)
L_0039: ret
}
So it turns out that, yes, these do generate identical IL. I was wrong originally. But that's not the whole story. It may be that I'm going off-topic here but I think that it's important to include this when talking about events and delegates:
Creating and comparing different delegates is not cheap.
When I wrote this, I was thinking that the first syntax was able to cast the method group as a delegate, but it turns out that it's just a conversion. But it's completely different when you actually save the delegate. If we add this to the consumer:
class Counter
{
EventHandler savedEvent;
public Counter()
{
savedEvent = CountEvent;
}
public void CountSaved()
{
producer.EventRaised += savedEvent;
producer.Raise();
producer.EventRaised -= savedEvent;
}
}
You can see that this has very different characteristics, performance-wise, from the other two:
static void Main(string[] args)
{
const int TestIterations = 10000000;
TimeSpan countTime = TestCounter(c => c.Count());
Console.WriteLine("Count: {0}", countTime);
TimeSpan countWithNewTime = TestCounter(c => c.CountWithNew());
Console.WriteLine("CountWithNew: {0}", countWithNewTime);
TimeSpan countSavedTime = TestCounter(c => c.CountSaved());
Console.WriteLine("CountSaved: {0}", countSavedTime);
Console.ReadLine();
}
static TimeSpan TestCounter(Action<Counter> action, int iterations)
{
var counter = new Counter();
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < TestIterations; i++)
action(counter);
sw.Stop();
return sw.Elapsed;
}
The results consistently come back as something similar to:
Count: 00:00:02.4742007
CountWithNew: 00:00:02.4272702
CountSaved: 00:00:01.9810367
That's nearly a 20% difference when using a saved delegate vs. creating a new one.
Now obviously not every program is going to be adding and removing this many delegates in such a small amount of time, but if you're writing library classes - classes that might be used in ways you cannot predict - then you really want to keep this difference in mind if you ever need to add and remove events (and I've written a lot of code that does this, personally).
So the conclusion of this is, writing SomeEvent += new EventHandler(NamedMethod)
compiles to the same thing as just SomeEvent += NamedMethod
. But if you plan to remove that event handler later, you really should save the delegate. Even though the Delegate
class has some special-case code that allows you to remove a referentially-different delegate from the one you added, it has to do a non-trivial amount of work to pull this off.
If you're not going to save the delegate, then it makes no difference - the compiler ends up creating a new delegate anyway.
wiring and unwiring event
Possibly because there is other code in between that will trigger the event, and they don't want eventHandler
to act on it. IMHO this isn't the best way to do things, but it's easy and it works.
If there is no other code in between there cannot possibly be a reason to remove and add the same event handler again.
C# why shall I use new keyword when subscribing for an event?
The verbose way works in all versions of C#, the short way only in C# 2 and later. So I see no reason to use the long way nowadays.
There are some situations where you still need to use new DelegateType(methodGroup)
, but event subscribing isn't one of them. These situations usually involve generic type inference or method overloading.
Unsubscribing will work either way since it is based on value equality, not referential equality. If I recall correctly both the implicit conversion from a method group and the explicit new
get translated to the same IL code. The implicit conversion is just syntax sugar.
Is there an actual difference in the 2 different ways of attaching event handlers in C#?
The second method is a shortcut to the first one, it was introduced in C# 2.0
See also this thread.
Wiring EventHandlers
Both are Exactly same.
But
Object.Event += EventHandler;
Object.Event -= EventHandler;
The above example compiles fine only in 3.0 or later version of C#, while if you are in 2.0 or before
you can only use following construct.
Object.Event += new System.EventHandler(EventHandler);
Object.Event -= new System.EventHandler(EventHandler);
Look more about at Type inferencing. search for "Type Inference"
Related Topics
What Does Synchronizationcontext Do
Opening a Folder in Explorer and Selecting a File
Debugging Automatic Properties
How to Convert an Object to a Byte Array in C#
How to Add CSS Class to HTML Generic Control Div
ASP.NET Core 2.0-2.2 Kestrel Not Serving Static Content
ASP.NET - Problems with Static Selected Style for a Selected Page on the Menu
When Do We Need to Set Processstartinfo.Useshellexecute to True
Implicit VS Explicit Interface Implementation
Passing a Vector/Array from Unmanaged C++ to C#
How to Intercept All Key Events, Including Ctrl+Alt+Del and Ctrl+Tab
Copy Constructor Versus Clone()
Getting Full Url of Action in ASP.NET MVC
Converting Xdocument to Xmldocument and Vice Versa
Is There an Alternative to String.Replace That Is Case-Insensitive