1

There are 3 classes A, B, C(Consumer). Class A calls B to fire event so that Class C can receive as it has subscribed. How to achieve this functionality?

Below is the code.

  public delegate void TestDelegate();
   public class B
 {
    public event TestDelegate TestEvent;

    public B()
    {

    }


    public void Fire()
    {
        TestEvent();//Null reference exception as not subscribed to the event as TestEvent is always null
    }
}
public class A
{
        static void Main()
{
 B b = new B();
b.Fire(); //Null reference exception as not subscribed to the event.
}
}

//Consumer application
public Class C
 {
  static void Main()
 {
 B b = new B();
 b.TestEvent+= new TestDelegate(c_TestEvent);

 }

    static void c_TestEvent()
      {
         Console.WriteLine("Console 2 Fired");
     }

 }
vsh
  • 53
  • 4
  • You have 2x `static void Main()`. Where does the program start? I think it starts in A, but you assume it starts in C. – Natrium May 08 '17 at 12:11
  • Start from reading about [event handlers](https://msdn.microsoft.com/en-us/library/edzehd2t(v=vs.110).aspx). They are multicast delegates and you must check for `null` before invoking. Alternative (outdated) is to subscribe empty delegate to event always, see [this](http://stackoverflow.com/q/4303343/1997232). – Sinatr May 08 '17 at 12:34

3 Answers3

1

Just ensure TestEvent is not null

public void Fire()
{
    if(TestEvent != null)
        TestEvent();
}

The newer way to do this using the safe navigation operator ?.

public void Fire()
{
    TestEvent?.Invoke();
}
Jamiec
  • 133,658
  • 13
  • 134
  • 193
0

There are multiple issues with your code

  • There are more than one Main (entry point). Don't know which one is taking precedence
  • There are more than one instance of B. The instance in A is firing the event whereas it does not have any event handler associated.

Refactor your code such that there is only one entry point into your application and also have one instance of B which will be used to subscribe to the event.

Gururaj
  • 539
  • 2
  • 8
  • Class C is a separate application. commented as consumer application – vsh May 08 '17 at 12:26
  • You're not calling the Fire method on the B instance inside Class 'C' and hence you don't get your method called. – Gururaj May 08 '17 at 12:28
0

Here's how to do it if you use the same instance of B:

using System;

namespace StackOverflow_Events
{
    class Program
    {
        static void Main(string[] args)
        {
            B b = new B();
            A a = new A(b);
            C c = new C(b);

            a.Test();

            Console.ReadKey();
        }
    }

    public delegate void TestDelegate();

    public class B
    {
        public event TestDelegate TestEvent;

        public B()
        {
        }

        public void Fire()
        {
            TestEvent?.Invoke();
        }
    }

    public class A
    {
        private B b;

        public A(B _b)
        {
            b = _b;
        }

        public void Test()
        {
            b.Fire(); 
        }
    }

    //Consumer application
    public class C
    {
        private B b;

        public C(B _b)
        {
            b = _b;
            b.TestEvent += new TestDelegate(c_TestEvent);
        }

        static void c_TestEvent()
        {
            Console.WriteLine("Console 2 Fired");
        }
    }

}

Here's how to do it statically:

using System;

namespace StackOverflow_Events
{
    class Program
    {
        static void Main(string[] args)
        {
            C.Init();

            A.Test();

            Console.ReadKey();
        }
    }

    public delegate void TestDelegate();

    public class B
    {
        public static event TestDelegate TestEvent;

        public B()
        {
        }

        public void Fire()
        {
            TestEvent?.Invoke();
        }
    }

    public class A
    {
        public static void Test()
        {
            B b = new B();
            b.Fire(); 
        }
    }

    //Consumer application
    public class C
    {
        public static void Init()
        {
            B.TestEvent += new TestDelegate(c_TestEvent);
        }

        static void c_TestEvent()
        {
            Console.WriteLine("Console 2 Fired");
        }
    }

}
C. McCoy IV
  • 887
  • 7
  • 14