Hello,

I am trying to invoke a method that sits in an object that is in a different namespace than the namespace that is doing the call. My problem is that the called object name is not known by the caller. I have prepared two examples that show what my problem is.

In both examples there is a window that has a button and a textbox; when the button is pressed the textbox shows the "Hello world" message. In the first example, since both objects are in the same namespace, the program works without a problem.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SameSpace
{
    public partial class Form1 : Form
    {
        WriterDriver writerDoer;

        public Form1()
        {
            InitializeComponent();

            WriterDelegateType writerHere = new WriterDelegateType(Writer);

            writerDoer = new WriterDriver(this, writerHere);
        }

        public void Writer()
        {
            textBox1.Text = "Hello world";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            writerDoer.DoIt();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SameSpace
{
    delegate void WriterDelegateType();

    class WriterDriver
    {
        Form1 form1Instance;
        WriterDelegateType writerDelegateInstance;

        public WriterDriver(Form1 form1InstanceArg, WriterDelegateType writerDelegateInstanceArg)
        {
            form1Instance = form1InstanceArg;
            writerDelegateInstance = writerDelegateInstanceArg;
        }

        public void DoIt()
        {
            form1Instance.Invoke(writerDelegateInstance);   
        }
    }
}

In this other example I have no way of entering the Invoke statement in the DoIt method so pressing the button does nothing.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SecondSpace; // This has been added

namespace FirstSpace
{
    public partial class Form1 : Form
    {
        WriterDriver writerDoer;

        public Form1()
        {
            InitializeComponent();

            WriterDelegateType writerHere = new WriterDelegateType(Writer);

            writerDoer = new WriterDriver(this, writerHere);
        }

        public void Writer()
        {
            textBox1.Text = "Hello world";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            writerDoer.Doit();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SecondSpace
{
    public delegate void WriterDelegateType(); // Here it's public

    public class WriterDriver
    {
        object form1Instance; // form1Instance is type object as Form1 is not known here
        WriterDelegateType writerDelegateInstance;

        // form1InstanceArg is type object as Form1 is not known here
        public WriterDriver(object form1InstanceArg, WriterDelegateType writerDelegateInstanceArg)
        {
            form1Instance = form1InstanceArg;
            writerDelegateInstance = writerDelegateInstanceArg;
        }

        public void Doit()
        {
            /*
             * Here I would like to type the equivalent to
             * 
             * form1Instance.Invoke(writerDelegateInstance);
             */
        }
    }
}

How can I Invoke the writerDelegateInstance that sits on a different namespace? I assume that I have to do some kind of type casting but I don't know what.

Thanks,
Enrique

Recommended Answers

All 10 Replies

If you want the second namespace to know about form1, you need to reference it with a using statement at the top of the code.

Then instead of having a generic object member, it can be of type Form1, and this should solve your problem of not being able to access its members.

The editor will not allow me to reference FirstSpace in SecondSpace as it claims I will create a circular reference.

Hello, Enrique.
I'm just wondering, why are you trying to access the method through form1Instance instance?

Why then you're creating a writerDelegateInstance delegate to store the reference to this method?

Also, to escape circular references, you can specify the full qualified name of a class (including it's namespace): SameSpace.Form1 .

Ah yeah didnt see you referenced secondnamespace in the first one. You will have to resolve it with the namespace name then:

namespace secondNamespace
{
   class myClass
   {
      Firstnamespace.Form1 myForm = new Firstnamespace.Form1()
   }
}

I entered this sentence

FirstSpace.Form1 form11Instance;

And got this error:

The type or namespace name 'FirstSpace' could not be found (are you missing a using directive or an assembly reference?)

Are these in seperate projects? I just tried it and it works if they are in the same project. If they are in seperate projects you will have to add a reference to the Firstspace project (you can do this in the solution explorer)

They are different projects. When I try to add a reference to the FirstSpace in the SecondSpace reference in the Solution Explorer I get back the Circular dependency error message.

Ok then .. going back to my previous question:
Why then you're creating a writerDelegateInstance delegate to store the reference to this method? .. if you don't really use it.

This is the tip of the iceberg.

I have a method that belongs to another object running in its own thread that handles serial communications with a piece of hardware. Then I have the user interface in an object that takes care of the Windows form, and in between there is an object that talks to both of these. Some of the messages that the hardware sends to the PC generate updates to some of the controls in the form and I get a cross threading error; my only solution is to execute the method that the communications object runs in order to update the form in the thread of the Windows form.

In addition to this I want the flexibility to be able to modify my form without having to rewrite the whole thing so the object that sits in the middle passes to the communications module delegates that point to the methods that update the form. This way I can modify the form without having to touch the innermost object, the communications object.

The two examples I posted are just the specific problem I have and are part of the big picture.

No-no .. I tried to lead you in other way.
In your program, you have both: reference to an object and reference to an assigned method. That's too many to call 1 single method.
If need to call the method, not depending on object, you can use this:
Delegates in C#
If you need to call method on a specific object (with thread considerations), you can take a look at this: Dispatcher Class

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.