Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call Delegate methods from another class

Tags:

c#

objective-c

I am having trouble figuring out how to program delegate method calls across classes in C#. I am coming from the world of Objective-C, which may be confusing me. In Objective-C, I can assign a delegate object inside a child class, to be the parent class (I.e., childViewcontroller.delegate = self;). Then I can to fire a method in the delegate class by using:

if([delegate respondsToSelector:@selector(methodName:)]) {
   [delegate methodName:parametersgohere];
}

However, I can't figure out how to do this in C#. I've read a bit about C# delegates in general (for example, here), but I'm still stuck.

Are there any examples that explain this?

Here is my scenario in full: I have classA which instantiates an instance of classB. ClassB fires a method (which call a web service), and upon response, I'd like to fire a method in classA.

Any 'Hello World' types of tutorials out there that might explain the very basics of this?

like image 207
Brett Avatar asked Apr 10 '12 18:04

Brett


2 Answers

A delegate is an object that points to a method, be it a static or instance method. So for your example, you would just use the event model:

class Caller {
    public void Call() {
        new Callee().DoSomething(this.Callback); // Pass in a delegate of this instance
    }

    public void Callback() {
        Console.WriteLine("Callback called!");
    }
}

class Callee {
    public void DoSomething(Action callback) {
        // Do stuff
        callback(); // Call the callback
    }
}

...

new Caller().Call(); // Callback called!

The Caller instance passes a delegate to the Callee instance's DoSomething method, which in turn calls the pointed-to method, which is the Callback method of the Caller instance.

like image 103
Ry- Avatar answered Sep 29 '22 18:09

Ry-


In C# what I think you are looking for are called events. They are a language feature that allows a class instance to expose a public delegate in a way that other class instances can subscribe to. Only the exposing class is allowed to raise the event.

In your example:

public class ClassB {
    // Note the syntax at the end here- the "(s, e) => { }" 
    // assigns a no-op listener so that you don't have to 
    // check the event for null before raising it.
    public event EventHandler<MyEventArgs> MyEvent = (s, e) => { }

    public void DoMyWork() { 
        // Do whatever

        // Then notify listeners that the event was fired
        MyEvent(this, new MyEventArgs(myWorkResult));
    }
}

public class ClassA {
    public ClassA(ClassB worker) {
        // Attach to worker's event
        worker.MyEvent += MyEventHandler;

        // If you want to detach later, use
        // worker.MyEvent -= MyEventHandler;
    }

    void MyEventHandler(Object sender, MyEventArgs e) {
        // This will get fired when B's event is raised
    }
}

public class MyEventArgs : EventArgs {
    public String MyWorkResult { get; private set; }
    public MyEventArgs(String myWorkResult) { MyWorkResult = myWorkResult; }
}

Note that the above will be synchronous. My understanding is that Objective-C delegates are all Actor pattern, so they are asynchronous. To make the above asynch, you'll need to delve into threading (probably want to google "C# Thread pool").

like image 44
Chris Shain Avatar answered Sep 29 '22 18:09

Chris Shain