1

I made this code in a class library named usedelegates:

namespace useofdelegates
{
    public class Class1
    {   //int i;
        public delegate void mydelegate(object sender,EventArgs e);
        public event mydelegate myevent;
        public void fire()
        {
           EventArgs ee = new EventArgs();
            myevent(this,ee);
        }

    }
}

Then in a windows form application, I intended to fire this event on the click of a button. The code in the form application is:

namespace WindowsFormsApplication9
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        useofdelegates.Class1 ob;
        private void button1_Click(object sender, EventArgs e)
        {
           // ob = new useofdelegates.Class1();
            ***ob.fire();***//give exception as object reference not set to an instance of     an object.*/
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            useofdelegates.Class1 ob = new useofdelegates.Class1();
            ob.myevent+=new useofdelegates.Class1.mydelegate(ob_myevent);
           // ob.fire();
        }
        public void ob_myevent(object sender, EventArgs e)
        {
            MessageBox.Show("hello hapiness");
        }


    }
}

This code on compiling throws an exception:

Object reference not set to an instance of an object.

but when I call ob.fire() in form_load(), it gives me the desired result without any exception. Why is this happening?

2 Answers 2

3

Several things:

The ob object is not a class variable (field) so each function needs to initialize it, register the event and then call it. You are doing this on the form load, but not on the button click.

Or rather, looking at your code, you are hiding the field in your form load by using a method variable with the same name.

This should work fine:

useofdelegates.Class1 ob;
private void button1_Click(object sender, EventArgs e)
{
  ob.fire();
}

private void Form1_Load(object sender, EventArgs e)
{
  ob = new useofdelegates.Class1();
  ob.myevent+=new useofdelegates.Class1.mydelegate(ob_myevent);
}

You also need to check that the delegate object is not null before calling it in the class that defines the event and delegate:

if (myevent != null)
   myevent(this,ee);

The thread safe version is this:

mydelegate eventcopy = myevent;
if (eventcopy != null)
   eventcopy(this,ee);
Sign up to request clarification or add additional context in comments.

4 Comments

I do agree that in a thread environment the latter is to be preferred but it's not thread safe :) It simply moves the responsibility of handling thread issues. What should happen if the handler is deregistered between if(eventcopy != null) and eventcopy(this,ee)? would it still be correct to call the eventhandler eventhough it's been deregistered? (depends I'd say)
@Rune FS - What do you suggest then? The code I have posted is idiomatic.
I'd didn't say there was anything wrong with the code. I just pointed out that it's commonly misconceived as being thread safe which it's not. What I would do depends and I would leave it up to the handler to determine what should happen. The code you wrote accomplishes never to deref null which makes it possible for the handler to make an informed decision whether to execute. That can be used to make the interaction thread safe so the code you present is a possible and often used first step to achieve thread safe handling but on its own it's just changing the threading issues not solving them
for an explanation of the problem see: blogs.msdn.com/b/ericlippert/archive/2009/04/29/…
1

You are hiding the member declaration for ob by redeclaring it as a local variable in Form_Load. Here's the way it should look:

    private void Form1_Load(object sender, EventArgs e)
    {
        ob = new useofdelegates.Class1();
        ob.myevent+=new useofdelegates.Class1.mydelegate(ob_myevent);
       // ob.fire();
    }

You are probably getting a waring about this from your compiler. It's always a good idea to try to eliminate compiler warnings.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.