How to use a C# .NET interface to send messages between classes

I have used delegates in Objective-C to send message back and forth between classes for years. (And in fact, I did a blog post on Setting up an Objective-C delegate for the iPhone SDK a few years back on this very subject.) Indeed, delegates are a critical part of the Objective-C language, as it is usually good for objects to be able to let other objects know what is going on.

Well now, in my .NET development duties, I have a very similar situation. My code has a bunch of user controls that I use, and I need to have messages sent from one user control to another as the user works with the various pieces of the application.

Of course, in order to keep the compiler happy and get it working, you can do something quick and dirty like putting in an instance variable into the class that points back to your user control, and then when you need to let that user control know what is going on, just use the instance variable reference to call a method in that user control’s class.

But this is not scalable. If you have a bunch of different user controls calling a specific user control, you would have to put a reference to each different type of calling control, and then walk through them and determine which one you need to call in each case.

C# interface to the rescue. By using a C# interface, you can put an instance variable for your interface into your called class, which will then allow your calling class (which of course follows the interface) to have a method fired in it.

Here is a tutorial using C# for a console application that demonstrates the principles:

using System;
 
namespace ConsoleApplication1
{
    interface IMyClass  // 1
    {
        void PassMessage(string theMessage);
    }
 
    public class MyClass  // 2
    {
        private IMyClass parentClass;  // 3
 
        public void SetParentClass(object c)  // 4
        {
            parentClass = c as IMyClass;
        }
 
        public void Nudge()  // 5
        {
            parentClass.PassMessage("MyClass hath been nudged.");
        }
    }
 
    public class MainClass : IMyClass  // 6
    {
        public void DoStuff()  // 7
        {
            Console.WriteLine("About to DoStuff in MainClass");
            var c = new MyClass();
            c.SetParentClass(this);
            c.Nudge();
 
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
 
        public void PassMessage(string theMessage)  // 8
        {
            Console.WriteLine("Message passed from MyClass: " + theMessage);
        }
    }
 
    public class Program
    {
        static void Main(string[] args)
        {
            var mainClass = new MainClass();
            mainClass.DoStuff();
        }
 
    }
}

So let’s break this down a bit. The numbers below correspond to the comments in the code above.

1. This is the interface definition. You need to put in here a listing of the methods that you want to be calling, sort of like an abstract class.

2. This is the class definition for the called class, or the class that needs to send a message back to the calling class.

3. Here is where the reference back to the calling class is kept. Since it’s type is an interface, any object that follows that interface can receive the caller’s message.

4. In this method, I am setting the reference back to the calling class. You can do this in the constructor as well if desired.

5. The Nudge method is a method in the called class that when executed, needs to send a message back to the calling class.

6. This is the class definition for the calling class. Notice that it follows the interface above, which requires that you provide the method specified in the interface.

7. This method creates the called class and sets up the interface reference, and then sends the Nudge message to the called class, which in turn calls back by firing the PassMessage method.

8. Here is where I do the processing necessary when the calling class is sending the message.

This is a pretty trivial example, but it should give you an idea on how to start setting up more complex cases.

BTW, Happy Birthday to John Myung, the fantastically talented bass player and founding member of Dream Theater. They are playing in a town near me this spring, but unfortunately I will be out of town and unable to see them. Great sadness.

Leave a Reply