about delegete

T

Tony Johansson

Hello!

Assume I have some classes and in this case the Ticker class below is
relevant for my question.
I have a Timer instance in this class with interval set to 1 second. When
the timer elapse efter each second it
will call the method handler OnTimeEvent. I have also a delegete declaration
here where the delegete type is Tick.
If no method has been added to the delegate variable tickers then tickers is
null.

Now to my question: When the eventhandler Notify is called as a result of
the timer has elapse and no method has been
added to the delegete variable then tickers is null. But when I run this
program is release I didn't get any NullReferenceException.when this method
was called "tickers(hours, minutes, seconds); " see below.

If I insted run the program in debug mode I get a nullReferenceException.

Can somebody explain that?
One more thing is it a good idea to check if tickes is null?


namespace Delegates
{
using System.Timers;

class Ticker
{
public delegate void Tick(int hh, int mm, int ss); //delegate
declaration
private Tick tickers; // delegate variable
private Timer ticking = new Timer(); // instansiate Timer
public Ticker() //C-tor
{
ticking.Elapsed += new ElapsedEventHandler(OnTimedEvent); //
eventhandler to be called when timer elapse
ticking.Interval = 1000; // 1 second interval
ticking.Enabled = true;
}

public void Add(Tick newMethod) // delegete type
{
//tickers += newMethod; //add method newMethod to delegete
}

public void Remove(Tick oldMethod) //delegete type
{
//tickers -= oldMethod; //remove method newMethod from delegate
}

private void Notify(int hours, int minutes, int seconds)
{
tickers(hours, minutes, seconds); //call hidden delegate method
}

//eventhandler that is called when timer is elapsing
private void OnTimedEvent(object source, ElapsedEventArgs args)
{
int hh = args.SignalTime.Hour;
int mm = args.SignalTime.Minute;
int ss = args.SignalTime.Second;
Notify(hh, mm, ss); // call notify
}
}
}

///Tony
 
P

Peter Duniho

[...]
Now to my question: When the eventhandler Notify is called as a resultof
the timer has elapse and no method has been
added to the delegete variable then tickers is null. But when I run this
program is release I didn't get any NullReferenceException.when this
method
was called "tickers(hours, minutes, seconds); " see below.

If I insted run the program in debug mode I get a nullReferenceException.

Can somebody explain that?

Off the top of my head, no. There's nothing in the code you posted that
would suggest that in any build, release or otherwise, that you should not
get a null reference exception when trying to invoke the null delegate
reference.

If you'd provided a concise-but-complete code sample, perhaps the answer
would be more apparent.
One more thing is it a good idea to check if tickes is null?

Yes, of course. You shouldn't dereference reference type variables until
you know for sure that they are non-null. You can either do this by
always initializing them to some known non-null value, or you can just
check for null before use.

As an example of the former, you could initialize "tickers" like this:

Tick ticker = delegate { };

Otherwise, yes...you should check the variable for null before trying to
invoke it.

Pete
 
T

Tony Johansson

Hello!
If I insted run the program in debug mode I get a nullReferenceException.

Can somebody explain that?
Off the top of my head, no. There's nothing in the code you posted that
would suggest that in any build, release or otherwise, that you should not
get a null reference exception when trying to invoke the null delegate
reference.
If you'd provided a concise-but-complete code sample, perhaps the answer
would be more apparent.

Here is a complete simple program example which consist of four classes.
There are two things in this example that are relevant for my question and
that is
Timers and delegate.
In this program example there is a Timer object which has a interval set to
1 second. When this
timer has elapse it will call the event handler OnTimedEvent. In this method
handler OnTimedEvent it will call
method Notify. In this method Notify it will call the delegate method that
has been added to the delegate variable
tickers. But if no method has been added do the delegate variable it will be
null. So if I run the program in relese mode and don't add a method to the
delegete variable tickers it will be null but I don't get any
nullReferenceException.
When I test and don't add a mehod to the delegete I just modify the program
and comment out these two lines below
tickers += newMethod; //add method newMethod to delegete
tickers -= oldMethod; //remove method newMethod from delegate

The Timer will still function elapsing every second even if no method has
been added to the delegete variable tickers.
But now to the strange thing if I run the program in debug mode I get a
nullReference Exception.

So as summery why do I get a nullReferenceExcetion in Debug but no in
release. I would be satisfied if I got a nullReferenceException in both
release and debug mode.


First you have the class Program below.
//Start class Program
//***************
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Delegates
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
}
}

//Start class Form1
//***************
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace Delegates
{
partial class Form1 : Form
{
private Clock clock;

public Form1()//C-tor
{
InitializeComponent();
clock = new Clock(digital);
}

private void start_Click(object sender, System.EventArgs e)
{
clock.Start();
}

private void stop_Click(object sender, System.EventArgs e)
{
clock.Stop();
}
}
}

//Start class Clock
//*************
using System.Windows.Forms;

namespace Delegates
{
class Clock
{
private Ticker pulsed = new Ticker();
private TextBox display;

public Clock(TextBox displayBox)//C-tor
{
display = displayBox;
}

public void Start()
{
pulsed.Add(RefreshTime); //Call add to add method
RefreshTime
}

public void Stop()
{
pulsed.Remove(RefreshTime);//call remove to remove method
RefreshTime
}

private void RefreshTime(int hh, int mm, int ss)
{
display.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", hh, mm,
ss);
}
}
}

//Start class Ticker
//*************
namespace Delegates
{
using System.Timers;

class Ticker
{
public delegate void Tick(int hh, int mm, int ss); //delegate
declaration
private Tick tickers; // delegate variable
private Timer ticking = new Timer(); // instansiate Timer

public Ticker() //C-tor
{
ticking.Elapsed += new ElapsedEventHandler(OnTimedEvent); //
eventhandler to be called when timer elapse
ticking.Interval = 1000; // 1 second interval
ticking.Enabled = true;
}

public void Add(Tick newMethod) // delegete type
{
tickers += newMethod; //add method newMethod to delegete
}

public void Remove(Tick oldMethod) //delegete type
{
tickers -= oldMethod; //remove method newMethod from delegate
}

private void Notify(int hours, int minutes, int seconds)
{
tickers(hours, minutes, seconds); //call hidden delegate
method
}

//eventhandler that is called when timer is elapsing
private void OnTimedEvent(object source, ElapsedEventArgs args)
{
int hh = args.SignalTime.Hour;
int mm = args.SignalTime.Minute;
int ss = args.SignalTime.Second;
Notify(hh, mm, ss); // call notify
}
}
}


//Tony


"Peter Duniho" <[email protected]> skrev i meddelandet
[...]
Now to my question: When the eventhandler Notify is called as a result of
the timer has elapse and no method has been
added to the delegete variable then tickers is null. But when I run this
program is release I didn't get any NullReferenceException.when this
method
was called "tickers(hours, minutes, seconds); " see below.

If I insted run the program in debug mode I get a nullReferenceException.

Can somebody explain that?

Off the top of my head, no. There's nothing in the code you posted that
would suggest that in any build, release or otherwise, that you should not
get a null reference exception when trying to invoke the null delegate
reference.

If you'd provided a concise-but-complete code sample, perhaps the answer
would be more apparent.
One more thing is it a good idea to check if tickes is null?

Yes, of course. You shouldn't dereference reference type variables until
you know for sure that they are non-null. You can either do this by
always initializing them to some known non-null value, or you can just
check for null before use.

As an example of the former, you could initialize "tickers" like this:

Tick ticker = delegate { };

Otherwise, yes...you should check the variable for null before trying to
invoke it.

Pete
 
B

Ben Voigt [C++ MVP]

Tony Johansson said:
Hello!




Here is a complete simple program example which consist of four classes.
There are two things in this example that are relevant for my question and
that is
Timers and delegate.
In this program example there is a Timer object which has a interval set
to 1 second. When this
timer has elapse it will call the event handler OnTimedEvent. In this
method handler OnTimedEvent it will call
method Notify. In this method Notify it will call the delegate method that
has been added to the delegate variable
tickers. But if no method has been added do the delegate variable it will
be null. So if I run the program in relese mode and don't add a method to
the delegete variable tickers it will be null but I don't get any
nullReferenceException.
When I test and don't add a mehod to the delegete I just modify the
program and comment out these two lines below
tickers += newMethod; //add method newMethod to delegete
tickers -= oldMethod; //remove method newMethod from delegate

The Timer will still function elapsing every second even if no method has
been added to the delegete variable tickers.
But now to the strange thing if I run the program in debug mode I get a
nullReference Exception.

So as summery why do I get a nullReferenceExcetion in Debug but no in
release. I would be satisfied if I got a nullReferenceException in both
release and debug mode.

I imagine that a NullReferenceException is generated and it terminates the
worker thread where the Timer callback is executing, you just didn't get any
message.
First you have the class Program below.
//Start class Program
//***************
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Delegates
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
}
}

//Start class Form1
//***************
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace Delegates
{
partial class Form1 : Form
{
private Clock clock;

public Form1()//C-tor
{
InitializeComponent();
clock = new Clock(digital);
}

private void start_Click(object sender, System.EventArgs e)
{
clock.Start();
}

private void stop_Click(object sender, System.EventArgs e)
{
clock.Stop();
}
}
}

//Start class Clock
//*************
using System.Windows.Forms;

namespace Delegates
{
class Clock
{
private Ticker pulsed = new Ticker();
private TextBox display;

public Clock(TextBox displayBox)//C-tor
{
display = displayBox;
}

public void Start()
{
pulsed.Add(RefreshTime); //Call add to add method
RefreshTime
}

public void Stop()
{
pulsed.Remove(RefreshTime);//call remove to remove method
RefreshTime
}

private void RefreshTime(int hh, int mm, int ss)
{
display.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", hh, mm,
ss);
}
}
}

//Start class Ticker
//*************
namespace Delegates
{
using System.Timers;

class Ticker
{
public delegate void Tick(int hh, int mm, int ss); //delegate
declaration
private Tick tickers; // delegate variable
private Timer ticking = new Timer(); // instansiate Timer

public Ticker() //C-tor
{
ticking.Elapsed += new ElapsedEventHandler(OnTimedEvent); //
eventhandler to be called when timer elapse
ticking.Interval = 1000; // 1 second interval
ticking.Enabled = true;
}

public void Add(Tick newMethod) // delegete type
{
tickers += newMethod; //add method newMethod to delegete
}

public void Remove(Tick oldMethod) //delegete type
{
tickers -= oldMethod; //remove method newMethod from delegate
}

private void Notify(int hours, int minutes, int seconds)
{
tickers(hours, minutes, seconds); //call hidden delegate
method
}

//eventhandler that is called when timer is elapsing
private void OnTimedEvent(object source, ElapsedEventArgs args)
{
int hh = args.SignalTime.Hour;
int mm = args.SignalTime.Minute;
int ss = args.SignalTime.Second;
Notify(hh, mm, ss); // call notify
}
}
}


//Tony


"Peter Duniho" <[email protected]> skrev i meddelandet
[...]
Now to my question: When the eventhandler Notify is called as a result of
the timer has elapse and no method has been
added to the delegete variable then tickers is null. But when I run this
program is release I didn't get any NullReferenceException.when this
method
was called "tickers(hours, minutes, seconds); " see below.

If I insted run the program in debug mode I get a nullReferenceException.

Can somebody explain that?

Off the top of my head, no. There's nothing in the code you posted that
would suggest that in any build, release or otherwise, that you should not
get a null reference exception when trying to invoke the null delegate
reference.

If you'd provided a concise-but-complete code sample, perhaps the answer
would be more apparent.
One more thing is it a good idea to check if tickes is null?

Yes, of course. You shouldn't dereference reference type variables until
you know for sure that they are non-null. You can either do this by
always initializing them to some known non-null value, or you can just
check for null before use.

As an example of the former, you could initialize "tickers" like this:

Tick ticker = delegate { };

Otherwise, yes...you should check the variable for null before trying to
invoke it.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top