I know how to use events, but how can I create a custom event?

Take the pointless class below:

class MyInt
{
int n;
public MyInt(int value)
{
n = value;
}
}

How would I create an event for it so that I can call a catching method
whenever the value is changed?

Re: How to Create Custom Events? by cfps

cfps
Thu Aug 28 08:41:51 CDT 2008

I know how I would do it:

public class IntEventArgs : EventArgs
{
private int _value;

public IntEventArgs(int Value)
{
_value = Value;
}

public int Value
{
get { return _value; }
}
}

public class MyInt
{
private int n;
public delegate void ValueChangedDelegate(object sender,
IntEventArgs e);
public event ValueChangedDelegate;

public MyInt(int value)
{
n = value;
}

public int Value
{
get { return n; }
set
{
n = value;
if (ValueChanged != null)
ValueChanged(this, new IntEventArgs(n);
}
}
}
}


Re: How to Create Custom Events? by Peter

Peter
Thu Aug 28 09:53:52 CDT 2008

On Thu, 28 Aug 2008 06:29:01 -0700, jp2msft
<jp2msft@discussions.microsoft.com> wrote:

> I know how to use events, but how can I create a custom event?
>
> Take the pointless class below:
>
> class MyInt
> {
> int n;
> public MyInt(int value)
> {
> n = value;
> }
> }
>
> How would I create an event for it so that I can call a catching method
> whenever the value is changed?

The other reply would work (almost...it's got at least one error, easily
found and fixed). But the canonical pattern for this sort of thing is to
just use a regular EventHandler:

class MyInt
{
int n;

public event EventHandler NChanged;

public MyInt(int n)
{
this.n = n;
}

public int N
{
get { return n; }
set
{
n = value;
RaiseNChanged();
}
}

private void RaiseNChanged()
{
EventHandler handler = NChanged;

if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}

(Of course, you can name the property anything else...it doesn't have to
be "N")

So now you have two options. :)

Pete

Re: How to Create Custom Events? by jp2msft

jp2msft
Thu Aug 28 10:28:02 CDT 2008

Great!

Now, on to how to make it impliment easily:

I see your code (sticking with the N property you used and I neglected to
include) would result in something like this:

MyInt Count = new MyInt(0);
// and alter to use it....
Count.N = Count.N + intNewValue;

Could the class be modified so that the workings of it are more transparent
(i.e. more like an 'int' or whatever value I am trying to mimic)?

Example:
MyInt Count = 0;
Count += intNewValue;

This is some cool theory stuff that typically is difficult to find.

"Peter Duniho" wrote:

> On Thu, 28 Aug 2008 06:29:01 -0700, jp2msft
> <jp2msft@discussions.microsoft.com> wrote:
>
> > I know how to use events, but how can I create a custom event?
> >
> > Take the pointless class below:
> >
> > class MyInt
> > {
> > int n;
> > public MyInt(int value)
> > {
> > n = value;
> > }
> > }
> >
> > How would I create an event for it so that I can call a catching method
> > whenever the value is changed?
>
> The other reply would work (almost...it's got at least one error, easily
> found and fixed). But the canonical pattern for this sort of thing is to
> just use a regular EventHandler:
>
> class MyInt
> {
> int n;
>
> public event EventHandler NChanged;
>
> public MyInt(int n)
> {
> this.n = n;
> }
>
> public int N
> {
> get { return n; }
> set
> {
> n = value;
> RaiseNChanged();
> }
> }
>
> private void RaiseNChanged()
> {
> EventHandler handler = NChanged;
>
> if (handler != null)
> {
> handler(this, EventArgs.Empty);
> }
> }
> }
>
> (Of course, you can name the property anything else...it doesn't have to
> be "N")
>
> So now you have two options. :)
>
> Pete
>

Re: How to Create Custom Events? by Peter

Peter
Thu Aug 28 10:58:01 CDT 2008

On Thu, 28 Aug 2008 08:28:02 -0700, jp2msft
<jp2msft@discussions.microsoft.com> wrote:

> [...]
> Could the class be modified so that the workings of it are more
> transparent
> (i.e. more like an 'int' or whatever value I am trying to mimic)?
>
> Example:
> MyInt Count = 0;
> Count += intNewValue;

Sure. You can overload the + operator for the class, to allow instances
of the class to be added to each other, as well as to provide for adding
an int to your class.

That said, I'll warn that things may start to get confusing if you do
this. Operator overloads can work very nicely for value types, but for a
mutable class, having a binary operator (for example) modify one of the
operands can result in some very non-intuitive code.

In particular, you can't overload +=. You have to overload +, and then
the compiler uses that overload when implementing +=. That means that if
this:

MyInt Count = new MyInt(0); // no overload of assignment operator
Count += intNewValue;

did what you expected, then this:

MyInt Count = new MyInt(0);
MyInt Other = Count + intNewValue;

might not do what you expect ("Other" would wind up referencing the same
instance as "Count", and that single instance of MyInt would have been
modified).

That's because the overload would have to look like this:

public static MyInt operator +(MyInt op1, int op2)
{
op1.N += op2;
return op1;
}

Now, all that said, you could write this:

MyInt Count = new MyInt(0); // no overload of assignment operator
Count.N += intNewValue;

without doing any operator overloading. That's almost as concise as your
desired syntax, but preserves the normal semantics for a mutable reference
type.

Pete

Re: How to Create Custom Events? by jp2msft

jp2msft
Thu Aug 28 12:38:06 CDT 2008

Beautiful! I'm writing all this down in an email that I'm forwarding to
myself for safe keeping.

I can't wait to start messing around with this new trick.

Thanks, Mr. Duniho!

"Peter Duniho" wrote:

> On Thu, 28 Aug 2008 08:28:02 -0700, jp2msft
> <jp2msft@discussions.microsoft.com> wrote:
>
> > [...]
> > Could the class be modified so that the workings of it are more
> > transparent
> > (i.e. more like an 'int' or whatever value I am trying to mimic)?
> >
> > Example:
> > MyInt Count = 0;
> > Count += intNewValue;
>
> Sure. You can overload the + operator for the class, to allow instances
> of the class to be added to each other, as well as to provide for adding
> an int to your class.
>
> That said, I'll warn that things may start to get confusing if you do
> this. Operator overloads can work very nicely for value types, but for a
> mutable class, having a binary operator (for example) modify one of the
> operands can result in some very non-intuitive code.
>
> In particular, you can't overload +=. You have to overload +, and then
> the compiler uses that overload when implementing +=. That means that if
> this:
>
> MyInt Count = new MyInt(0); // no overload of assignment operator
> Count += intNewValue;
>
> did what you expected, then this:
>
> MyInt Count = new MyInt(0);
> MyInt Other = Count + intNewValue;
>
> might not do what you expect ("Other" would wind up referencing the same
> instance as "Count", and that single instance of MyInt would have been
> modified).
>
> That's because the overload would have to look like this:
>
> public static MyInt operator +(MyInt op1, int op2)
> {
> op1.N += op2;
> return op1;
> }
>
> Now, all that said, you could write this:
>
> MyInt Count = new MyInt(0); // no overload of assignment operator
> Count.N += intNewValue;
>
> without doing any operator overloading. That's almost as concise as your
> desired syntax, but preserves the normal semantics for a mutable reference
> type.
>
> Pete
>