tags:

views:

1893

answers:

5
+1  Q: 

Callbacks in C#

I want to have a library that will have a function in it that accepts an object for it's parameter.

With this object I want to be able to call a specified function when X is finished. The function that will be called is to be specified by the caller, and X will be done and monitored by the library.

How can I do this?

For reference I'm using C# and .NET 3.5

+1  A: 

The object in question will need to implement an interface provided by you. Take the interface as a parameter, and then you can call any method that the interface exposes. Otherwise you have no way of knowing what the object is capable of. That, or you could take a delegate as a parameter and call that.

Ed Swangren
This is exactly correct.
plinth
+3  A: 

Sounds like a perfect recipe for delegates - in particular, callbacks with delegates are exactly how this is handled in the asynchronous pattern in .NET.

The caller would usually pass you some state and a delegate, and you store both of them in whatever context you've got, then call the delegate passing it the state and whatever result you might have.

You could either make the state just object or potentially use a generic delegate and take state of the appropriate type, e.g.

public delegate void Callback<T>(T state, OperationResult result)

Then:

public void DoSomeOperation(int otherParameterForWhateverReason,
                            Callback<T> callback, T state)

As you're using .NET 3.5 you might want to use the existing Func<...> and Action<...> delegate types, but you may find it makes it clearer to declare your own. (The name may make it clearer what you're using it for.)

Jon Skeet
I don't understand what you're talking about...
Malfist
I suggest you read up on delegates then (and generics, potentially). My article on delegates and evvents is at http://pobox.com/~skeet/csharp/events.html
Jon Skeet
A: 

Is there a reason not to have your library provide a public event to be fired when the operation is complete? Then the caller could just register to handle the event and you don't have to worry about passing around objects or delegates.

The object implementing an interface you have provided would work, but it seems to be more the Java approach than the .NET approach. Events seem a bit cleaner to me.

Cory McCarty
I don't know how to do events...
Malfist
See http://pobox.com/~skeet/csharp/events.html to learn about events. They may or may not be appropriate for your situation, but they're worth knowing about.
Jon Skeet
+3  A: 

Supply a delegate and use an anonymous delegate or Lambda Expression

public static void DoWork(Action processAction)
{
  // do work
  if (processAction != null)
    processAction();
}

public static void Main()
{
  // using anonymous delegate
  DoWork(delegate() { Console.WriteLine("Completed"); });

  // using Lambda
  DoWork(() => Console.WriteLine("Completed"));
}

Or use an interface

public interface IObjectWithX
{
  void X();
}

public class MyObjectWithX : IObjectWithX
{
  public void X()
  {
    // do something
  }
}

public class ActionClass
{
  public static void DoWork(IObjectWithX handlerObject)
  {
    // do work
    handlerObject.X();
  }
}

public static void Main()
{
  var obj = new MyObjectWithX()
  ActionClass.DoWork(obj);
}
bendewey
A: 

http://www.billb.name/it/Callbacks.asp

for an explanation using either a delegate or an interface.

BillB