Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What to use? delegate, event, or Func<T>?

I want to provide objects within a class library the ability to “output” messages without worrying about how it is being output. The class library could be used in a console app, a WinForm or WPF windows application, or a web page.

I’d originally decided that I would use a delegate to handle this. I implemented this using classes but the compiler did not like the delegate when I attempted to put the delegate into an interface that each of these objects inherent from.

I found that I could move the delegate out of the interface and then was able to compile but I'm not sure that this accomplishes what I am trying to do.. It also seems like a kludge so I wanted to ask if any of you have different ideas to accomplish this…

The Interface:

namespace Test
{
  using System;
  using System.Xml.Linq;

  public interface IAction
  {
    DisplayMessageDelegate DisplayMessage(string message);
    void Execute();
    XElement Serialize(XName elementName);
  }

  public delegate void DisplayMessageDelegate(string message);
}

From there, I'm not sure how to implement this behavior: (BTW, I know that this code will not compile...)

public class ActionClass1 : IAction
{
  // Other methods not shown...
  void Execute()
  {
    if (this.DisplayMessage != null)
    {
      this.DisplayMessage(“Hello”);
    }
  }
}

public class ConsoleClass
{
  ActionClass1 class1 = new ActionClass1();
  class1.DisplayMessage = { x =>  Console.WriteLine(x); };
}

public class WinFormClass
{
  ActionClass1 class1 = new ActionClass1();
  Class1.DisplayMessage = {x => DisplayTextBox.Text = x; };
}
like image 384
Julian Easterling Avatar asked Apr 08 '11 21:04

Julian Easterling


1 Answers

If you want the ability to hook up multiple delegates to respond to a single call to Execute, I would definitely use an event. If you only want a single action to be hooked up, use an Action or a Func delegate.

For your example, one of the Action delegates should work. In your case, it would be Action<string> since your delegate takes a string argument. An Action is simply a delegate that takes zero or more arguments and returns void. It appears that you aren't returning anything, so that's why I'm suggesting Action.

You only want to use a Func<TResult> if your delegate needs to return something. The difference between Func and Action is that Func delegates have a return type, and Action delegates do not. Either of these delegates have generic versions that can take up to 16 or so arguments.

If you need more than 16 arguments on a delegate you might want to reconsider the design :)

like image 128
Andy White Avatar answered Oct 19 '22 04:10

Andy White