23

After reading the article- When to Use Delegates Instead of Interfaces (C# Programming Guide), I need some help understanding the below given points, which I found to be not so clear (for me). Any examples or detailed explanations available for these?

Use a delegate when:

  • An eventing design pattern is used.
  • It is desirable to encapsulate a static method.
  • Easy composition is desired.
  • A class may need more than one implementation of the method.

Use an interface when:

  • There are a group of related methods that may be called.
  • A class only needs one implementation of the method.

My Questions are,

  1. What do they mean by an eventing design pattern?
  2. How the composition turns out to be easy if a delegate is used?
  3. if there is a group of related methods that may be called,then use interface-What benefit it has?
  4. if a class only needs one implementation of the method, use interface-how is it justified in terms of benefits?
0

9 Answers 9

12

What do they mean by an eventing design pattern?

They most likely refer to an implementation of the observer pattern which is a core language construct in C#, exposed as 'events'. Listening to events is possible by hooking a delegate to them. As Yam Marcovic pointed out, EventHandler is the conventional base delegate type for events, but any delegate type can be used.

How the composition turns out to be easy if a delegate is used?

This probably just refers to the flexibility delegates offer. You can easily 'compose' certain behavior. With the help of lambdas, the syntax to do this is also very concise. Consider the following example.

class Bunny
{
    Func<bool> _canHop;

    public Bunny( Func<bool> canHop )
    {
        _canHop = canHop;
    }

    public void Hop()
    {
        if ( _canHop() )  Console.WriteLine( "Hop!" );
    }
}

Bunny captiveBunny = new Bunny( () => IsBunnyReleased );
Bunny lazyBunny = new Bunny( () => !IsLazyDay );
Bunny captiveLazyBunny = new Bunny( () => IsBunnyReleased && !IsLazyDay );

Doing something similar with interfaces would require you to either use the strategy pattern or using an (abstract) base Bunny class from which you extend more specific bunnies.

if there is a group of related methods that may be called, then use interface-What benefit it has?

Again, I'll use bunnies to demonstrate how it would be easier.

interface IAnimal
{
    void Jump();
    void Eat();
    void Poo();
}

class Bunny : IAnimal { ... }
class Chick : IAnimal { ... }

// Using the interface.
IAnimal bunny = new Bunny();
bunny.Jump();  bunny.Eat();  bunny.Poo();
IAnimal chick = new Chick();
chick.Jump();  chick.Eat();  chick.Poo();

// Without the interface.
Action bunnyJump = () => bunny.Jump();
Action bunnyEat = () => bunny.Eat();
Action bunnyPoo = () => bunny.Poo();
bunnyJump(); bunnyEat(); bunnyPoo();
Action chickJump = () => chick.Jump();
Action chickEat = () => chick.Eat();
...

if a class only needs one implementation of the method, use interface-how is it justified in terms of benefits?

For this, consider the first example with the bunny again. If only one implementation is ever needed - no custom composition is ever required -, you can expose this behavior as an interface. You will never have to construct the lambdas, you can just use the interface.

Conclusion

Delegates offer a lot more flexibility, while interfaces help you establish strong contracts. Therefore I find the last point mentioned, "A class may need more than one implementation of the method.", by far the most relevant one.

An additional reason when to use delegates is when you want to expose only part of a class which you can't adjust the source file from.

As an example of such a scenario (maximum flexibility, no need to modify sources), consider this implementation of the binary search algorithm for any possible collection by just passing two delegates.

12

A delegate is something like an interface for a single method signature, that doesn't have to be explicitly implemented like a regular interface. You can construct it on the run.

An interface is just a language structure representing some contract - "I hereby guarantee I make the following methods and properties available".

Also, I don't completely agree that delegates are primarily useful when used as an solution to the observer/subscriber pattern. It is, however, en elegant solution to the "java verbosity problem".

For your questions:

1 & 2)

If you want to create an event system in Java you typically use an interface to propagate the event, something like:

interface KeyboardListener
{
    void KeyDown(int key);
    void KeyUp(int key)
    void KeyPress(int key);
    .... and so on
}

This means your class will have to explicitly implement all these methods, and provide stubs for all of them even if you simply want to implement KeyPress(int key).

In C#, these events would be represented as lists of delegate, hidden by the "event" keyword in c#, one for each singular event. This means you can easily subscribe to what you want without burdening your class with public "Key" methods etc.

+1 for points 3-5.

Additionally:

Delegates are very useful when you want to supply for example a "map" function, that takes a list and projects each element into a new list, with the same amount of elements, but different in some way. Essentially, IEnumerable.Select(...).

IEnumerable.Select takes a Func<TSource, TDest>, which is a delegate wrapping a function that takes a TSource element and transforms that element into a TDest element.

In Java this would have to be implemented using an interface. There is often no natural place to implement such an interface. If a class contains a list that it wants to transform in some way, it's not very natural that it implements the interface "ListTransformer", especially since there might be two different lists that should be transformed in different ways.

Of course, you could use anonymous classes which are a similar concept (in java).

3
  • Consider editing your post to actually answer his questions Oct 19, 2011 at 17:57
  • @YamMarcovic You are right, I rambled a bit in freeform instead of directly answering his questions. Still, I think it explains a bit about the mechanics involved. Also, his questions were a bit less well-formed when I answered the question. :p
    – Max
    Oct 24, 2011 at 12:09
  • Naturally. Happens to me as well, and it does have its value per se. That's why I only suggested it, but didn't complain about it. :) Oct 24, 2011 at 14:51
3

1) Eventing patterns, well the classic is the Observer pattern, here's a good Microsoft link Microsoft talk Observer

The article you linked to isn't very well written imo and makes things more complicated than necessary. The static business is common sense, you can't define an interface with static members, so if you want polymorphic behaviour on a static method you would use a delegate.

The link above talks about delegates and why there are good for composition, so that might help with your query.

3

First of all, good question. I admire your focus on utility rather than blindly accepting "best practices". +1 for that.

I've read that guide before. You have to remember something about it - it is just a guide, mainly for C# newcomers who know how to program but aren't so familiar with the C# way of doing things. It's not so much as a page of rules as it is a page that describes how things are already usually done. And since they're already done this way everywhere, it might be a good idea to stay consistent.

I'll get to the point, answering your questions.

First of all, I assume you already know what an interface is. As for a delegate, it's enough to say that it's a structure containing a typed pointer to a method, along with an optional pointer to the object representing the this argument for that method. In case of static methods, the latter pointer is null.
There are also Multicast delegates, which are just like delegates, but may have several of these structures assigned to them (meaning a single call to Invoke on a multicast delegate invokes all of the methods in its assigned invocation list).

What do they mean by an eventing design pattern?

They mean using events in C# (which has special keywords for sophistically implementing this extremely useful pattern). Events in C# are fueled by multicast delegates.

When you define an event, such as in this example:

class MyClass {
  // Note: EventHandler is just a multicast delegate,
  // that returns void and accepts (object sender, EventArgs e)!
  public event EventHandler MyEvent;

  public void DoSomethingThatTriggersMyEvent() {
    // ... some code
    var handler = MyEvent;
    if (handler != null)
      handler(this, EventArgs.Empty);
    // ... some other code
  }
}

The compiler actually transforms this into the following code:

class MyClass {
  private EventHandler MyEvent = null;

  public void add_MyEvent(EventHandler value) {
    MyEvent += value;
  }

  public void remove_MyEvent(EventHandler value) {
    MyEvent -= value;
  }

  public void DoSomethingThatTriggersMyEvent() {
    // ... some code
    var handler = MyEvent;
    if (handler != null)
      handler(this, EventArgs.Empty);
    // ... some other code
  }
}

You then subscribe to an event by doing

MyClass instance = new MyClass();
instance.MyEvent += SomeMethodInMyClass;

Which compiles down to

MyClass instance = new MyClass();
instance.add_MyEvent(new EventHandler(SomeMethodInMyClass));

So that's eventing in C# (or .NET in general).

How the composition turns out to be easy if a delegate is used?

This may easily be demonstrated:

Suppose you have a class that depends on a set of actions to be passed to it. You could encapsulate those actions in an interface:

interface RequiredMethods {
  void DoX();
  int DoY();
};

And anyone who wanted to pass actions to your class would first have to implement that interface. Or you could make their lives easier by depending on the following class:

sealed class RequiredMethods {
  public Action DoX;
  public Func<int> DoY();
}

This way the callers only have to create an instance of RequiredMethods and bind methods to the delegates at runtime. This is usually easier.

This way of doing things is extremely beneficial under the right circumstances. Think about it - why depend on an interface when all you really care about is having an implementation passed to you?

Benefits of using interfaces when there are a group of related methods

It's beneficial to use interfaces because interfaces normally require explicit compile-time implementations. This means that you create a new class.
And if you have a group of related methods in a single package, it's beneficial to have that package be reusable by other parts of the code. So if they can simply instantiate a class instead of building a set of delegates, it's easier.

Benefits of using interfaces if a class only needs one implementation

As noted earlier, interfaces are implemented in compile time -- which means they are more efficient than invoking a delegate (which is a level of indirection per se).

"One implementation" might mean an implementation that exists a single well-defined place.
Otherwise an implementation might come from anywhere in the program which just happens to conform to the method signature. That allows for more flexibility, because methods need only to conform to the expected signature, rather than belong in a class that explicitly implements a specific interface. But that flexibility might come at a cost, and actually breaks the Liskov Substitution principle, because most times you want explicitness, because it minimizes the chance for accidents. Just like Static Typing.

The term might also refer to multicast delegates here. Methods declared by interfaces can only be implemented once in an implementing class. But delegates can accumulate multiple methods, which will be called sequentially.

So all in all, it looks like the guide is not informative enough, and merely functions as what it is - a guide, not a rulebook. Some advice might actually sound a bit contradictive. It's up to you to decide when it's right to apply what. The guide seems to only give us a general path.

I hope your questions have been answered to your satisfaction. And again, kudos for the question.

2

If my memory of .NET still holds, a delegate is basically a function ptr or functor. It adds a layer of indirection to a function call so that functions can be substituted without the calling code having to change. This is the same thing an interface does, except that an interface packages multiple functions together, and an implementor has to implement them together.

An event pattern, broadly speaking, is one where something responds to events from elswhere (such as Windows messages). The set of events is usually open ended, they can come in any order, and are not necessarily related to each other. Delegates work well for this in that each event can call a single function without needing a reference to a series of implementing objects that might also contain numerous irrelevant functions. In addition (this is where my .NET memory is vague), I think multiple delegates can be attached to an event.

Compositing, though I am not very familiar with the term, is basically designing one object to have multiple sub-parts, or aggregated children to which the work is passed down. Delegates allow the children to be mixed and matched in a more ad-hoc way where an interface might be overkill or cause too much coupling and the rigidity and fragility that comes with it.

The benefit to an interface for related methods is that the methods can share the state of the implementing object. Delegate functions cannot so cleanly share, or even contain, state.

If a class needs a single implementation, an interface is more suitable since within any class implementing the whole collection, only one implementation can be done, and you get the benefits of an implementing class (state, encapsulation. etc). If the implementation might change due to runtime state, delegates work better because they can be swapped out for other implementations without effecting the other methods. For instance, if there are three delegates that each have two possible implementations, you would need eight different classes implementing the three-method interface to account for all the possible combinations of states.

1

The "eventing" design pattern (better known as the Observer Pattern) allows you to attach multiple methods of the same signature to the delegate. You can't really do that with an interface.

I'm not at all convinced that composition is easier for a delegate than an interface though. That's a very odd statement. I wonder if he means because you can attach anonymous methods to a delegate.

1

The biggest clarification I can offer:

  1. A delegate defines a function signature - which parameters a matching function will accept and what it will return.
  2. An interface deals with a whole set of functions, events, properties, and fields.

So:

  1. When you want to generalize some functions with the same signature - use a delegate.
  2. When you want to generalize some behavior or quality of a class - use an interface.
1

Your question on events has already been nicely covered. And it is also true, that an interface can define multiple methods (but actually needn't), while a function type only ever puts constraints on an individual function.

The real difference however is:

  • function values are matched to function types by structural subtyping (i.e. implicit compatibility to demanded structure). That means, if a function value has a signature compatible to the function type, it is a valid value for the type.
  • instances are matched to interfaces by nominal subtyping (i.e. explicit use of a name). That means, if an instance is a member of a class, that explicitly implements the given interface, the instance is a valid value for the interface. However, if the object only has all members demanded by the interfaces, and all members have compatible signatures, but does not explicitly implement the interface, it is not a valid value for the interface.

Sure, but what does this mean?

Let's take this example (code is in haXe since my C# isn't very good):

class Collection<T> {
    /* a lot of code we don't care about now */
    public function filter(predicate:T->Bool):Collection<T> { 
         //build a new collection with all elements e, such that predicate(e) == true
    }
    public function remove(e:T):Bool {
         //removes an element from this collection, if contained and returns true, false otherwise
    }
}

Now the filter-method makes it easy to conveniently pass in just a small piece of logic, that is unaware of the internal organisation of the collection, while the collection doesn't depend on the logic given to it. Great. Except for one problem:
The collection does depend on the logic. The collection inherently makes the assumption, that the function passed in is designed to test a value against a condition and return the success of the test. Note that not all functions, that take one value as an argument and return a boolean are actually mere predicates. For example our collection's remove method is such a function.
Assume we called c.filter(c.remove). The result would be a collection with all the elements of c while c itself becomes empty. This is unfortunate, because naturally we'd expect c itself to be invariant.

The example is very constructed. But the key problem is, that the code calling c.filter with some function value as argument has no way of knowing whether that argument is suitable (i.e. will ultimately conserve the invariant). The code that created the function value may or may not know, that it will be interpreted as a predicate.

Now let's change things:

interface Predicate<T> {
    function test(value:T):Bool;
}
class Collection<T> {
    /* a lot of code we don't care about now */
    public function filter(predicate:Predicate<T>):Collection<T> { 
         //build a new collection with all elements e, such that predicate.test(e) == true
    }
    public function remove(e:T):Bool {
         //removes an element from this collection, if contained and returns true, false otherwise
    }
}

What has changed? What has changed is, that whatever value is now given to filter has explicitly signed the contract of being a predicate. Of course malicious or extremely stupid programmers create implementations of the interface that aren't side-effect free and thus aren't predicates.
But what can no longer happen is that someone ties up a logical unit of data/code, which mistakenly get's interpreted as a predicate because of its outer structure.

So to rephrase what was said above in just a few words:

  • interfaces mean using nominal typing and thereby explicit relationships
  • delegates mean using structural typing and thereby implicit relationships

The advantage of explicit relationships is, that you can be certain of them. The disadvantage is, that they require the overhead of explicitness. Conversely, the disadvantage of implicit relationships (in our case one function's signature matching the desired signature), is that you can't really be 100% sure that you can use things this way. The advantage is, that you can establish relationships without all the overhead. You can just quickly throw things together, because their structure allows it. That's what easy composition means.
It's a bit like LEGO: you can simply plug a star wars LEGO figure onto a LEGO pirate ship, simply because outer structure allows it. Now you might feel that that is terribly wrong, or it might just be exactly what you want. Nobody is going to stop you.

2
  • 1
    It's worth mentioning that "explicitly implements the interface" (under "nominal subtyping") is not the same as explicit or implicit implementation of interface members. In C#, classes must always explicitly declare the interfaces they implement, as you say. But interface members may be implemented either explicitly (e.g., int IList.Count { get { ... } }) or implicitly (public int Count { get { ... } }). This distinction isn't relevant to this discussion, but it deserves mention to avoid confusing readers.
    – phoog
    Oct 21, 2011 at 22:19
  • @phoog: Yes, thanks for the amendment. I didn't even know the first one was possible. But yes, the way how a language actually enforces interface implementation varies a lot. In Objective-C for example, it will only give you a warning if its not implemented.
    – back2dos
    Oct 24, 2011 at 10:02
1
+50
  1. An eventing design pattern implies a structure which involves a publish and subscribe mechanism. Events are published by a source, every subscriber gets it's own copy of the published item and is responsible for it's own actions. That is a loosely coupled mechanism because the publisher doesn't even have to know the subscribers are there. Let alone having subscribers is not mandatory (ther can be none)
  2. composition is "easier" if a delegate is used compared to an interface. Interfaces define a class instance as being a "kind of handler" object where as a composition construct instance appears to "have a handler" therefore the appearance of the instance is less restricted by using a delegate and becomes more flexible.
  3. From comment below I've found that I needed to improve my post, see this for reference: http://bytes.com/topic/c-sharp/answers/252309-interface-vs-delegate
6
  • 1
    3. Why would delegates require more casting, and why is tighter coupling a benefit? 4. You don't have to use events to use delegates, and with delegates it's just like holding a method - you know it's return type and it's arguments' types. Also, why would a method declared in an interface make it easier to handle errors than a method attached to a delegate? Oct 20, 2011 at 11:13
  • In case of just the spec of a delegate you are right. In the case of event handling however(at least that's what my reference is pertaining to) you alway need to inherit form some kind of eventArgs to act as container for custom types, so instead of being able to safely test for a value you would always have to unwrap your type before handling the values.
    – Carlo Kuip
    Oct 20, 2011 at 15:22
  • As for the reason why I think a method defined in an interface would make it easier to handle errors is having the compiler being able to check the exception types thrown from that method. I know it's not convincing evidence but maybe should be stated as preference?
    – Carlo Kuip
    Oct 20, 2011 at 15:32
  • 1
    Firstly we were talking about delegates vs interfaces, not events vs interfaces. Secondly, making an event base itself on an EventHandler delegate is just a convention, and by no means mandatory. But again, talking about events here kind of misses the point. As for your second comment - exceptions aren't checked in C#. You're getting confused with Java (which incidentally doesn't even have delegates). Oct 20, 2011 at 16:37
  • Found a thread on this subject explaining important differences:bytes.com/topic/c-sharp/answers/252309-interface-vs-delegate
    – Carlo Kuip
    Oct 20, 2011 at 18:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.