Tuesday, September 06, 2005

C# events compared to Delphi events

Events in C# are, like in Delphi (or should I say Object Pascal) just properties of a class. Events are method pointers that delegate a call to the calling class. Just as in Delphi for .NET you can add multiple event handlers to an event.

An event has three main parts:

1. A method pointer property
2. The raising of the event
3. An event handler

1. A method pointer property.
Delphi and C# have a lot standard method pointer types. The most common Delphi method pointer type is the TNotifyEvent. In C# (or in .NET framework) this is the System.EventHandler.
You can use this methods, but you can also make your own.

Defining a method pointer type:
In C#:
public delegate void OnSomething(object Sender, int Value);

In .NET you could, of course, store the parameters in a (derived) System.EventArgs object.

In Delphi:
TOnSomething = procedure(Sender : TObject; Value : Integer) of Object;

They are just types that must be available for the object that uses them.

The class that wants to raise the event must have a public property for it:
In C#:
public event OnSomething BeforeSomething;

In Delphi:
property BeforeSomething : TOnSomething read FBeforeSomething write BeforeSomething;
(Where FBeforeSomething is a private field of the same type)

2. Raising the event
In this example the BeforeSomething event is raised. If the calling class has assigned the property to the (event) class this one can raise it.

In C#:
public virtual void LetItHappen()
{
// The class should add a valid integer value for the event, here 10
if (OnSomething!= null) OnSomething(this, 10);
}
}


In Delphi:
procedure
TSomeClass.LetItHappen;
begin
if Assigned(FOnSomething) then FOnSomething(Self, 10);
end;

You must check if the property is assigned else you will get an access violation.

The code for C# and Delphi is amazingly similar. You can make it more similar if you like:

private bool Assigned(object AObject)
{
if (AObject != null)
return true;
else
return false;
}

the C# code then could be:
if Assigned(OnSomething) OnSomething(this, 10);
;-)

3. The eventhandler
In the calling object you should first make an event handler method:
(Suppose the calling is SomeObject : TSomeClass)

In C#:
private void MyBeforeSomething(object Sender, int Value)
{
MessageBox.Show(Value.ToString());
}

In Delphi:
procedure
TSomeClass.MyBeforeSomething(Sender : TObject; Value :
Integer);
begin
ShowMessage(IntToStr(Value);
end;

The last thing you should do now is assigning the property:

In C#:
SomeObject.BeforeSomething += new OnSomething(MyBeforeSomething);

A new handler is added to list of handlers (or listners). You can remove them by using '-='

In Delphi:
SomeObject.BeforeSomething := MyBeforeSometing;

In Delphi for .NET you can also add multiple handlers (listners) for an
event, using the Include en Exclude methods.

Events in C# are basically the same as in Delphi. C# must be Delphi's little brother, no doubt about that.
More information on events in C# can be found on MSDN here.

8 comments:

Anonymous said...

It's far away from to be the same!

C# has multicast events by default. Remember += ?! Delphi doesn't... :-(

Another problem will riaise when one need to use delegate. In C# it supported natively, in delphi no.

That will make thing complicated when one need, let say, callback in remoting.

So, it's not even close to be the same...

Anonymous said...

1) Having multicast as default doesn't make C# better... just different

2) Delegates are native in Delphi since Delphi 1 :)

Anonymous said...

For Multicast in Delphi you must declare :
property BeforeSomething : TOnSomething add FBeforeSomething remove FBeforeSomething;

Or using Include | Exclude :
Include(SomeObject.BeforeSomething, MyBeforeSometing); // += in C#

Exclude(SomeObject.BeforeSomething, MyBeforeSometing); // -= in C#

Anonymous said...

@anonymous
OK, did not know about add and remove gone give that a try...

Thanks!

Мирослав Пенчев said...

I cannot find anything in Delphi documentation about multicast events. Any ideas where to look?

Anonymous said...

Hello,

please look in the Delphi 2005 demo project "WebServiceClient". You can find this in the
\Demos\Delphi.Net\CLR\MapQuest Folder.

The Unit PetrVones.Utils.SoapTrace have 2 Mulicast Event Handlers.

Thanks
Matt

Anonymous said...

Some seem to have forgotten that C# was headed up and designed by the guy responsible for the dcc32 compiler of delphi and the object pascal object model and core language structure.

THAT is why c# is similar to delphi!

There are good and bad points about both languages, so far im still on the delphi side of the street (for power, language syntax and object model is awesome compared)

BiBi said...

What is wrong with this C# ???
In Delphi I can do something like this:

procedure (...).GetEvents( ... )
begin
(...)
vNewControl.OnClick := iOldControl.OnClik;
end;

In C# I cannot
vNewControl.Click += iOldControl.Click;

Why? Why? Why? And what should I do
to see the same effect in C#?