Delegates VS interfaces - some confusion


B

beginwithl

hi

Sorry for so many questions ( again )

What follows are excerpts from msdn article regarding the differences
between interfaces and delegates and when you should choose one over
the other. Anyways, I don’t quite understand the arguments they
present:

msdn:

“Use a delegate in the following circumstances:
• It is desirable to encapsulate a static method.
• A class may need more than one implementation of the method."



a) “It is desirable to encapsulate a static method.”

I assume they are referring to the fact that interfaces can’t declare
static methods and thus if you want to call a static method, you
should choose a delegate?



“A class may need more than one implementation of the method.”


b) What class are they referring to? An observer class or publisher
class?


c) By ”By more than one implementation of the method” are they
talking about method overloading? But, interface methods can also be
overloaded!


d) In any case, I don’t understand how needing more than one method
implementation qualifies a delegate as being more appropriate?




2)

Continuing with msdn article:

“Use an interface in the following circumstances:
• A class only needs one implementation of the method.
• The class using the interface will want to cast that interface to
other interface or class types.
• The method being implemented is linked to the type or identity of
the class: for example, comparison methods. “


a) “A class only needs one implementation of the method.”

This question is sort of continuation of the previous one: So why is
interface more appropriate if class only needs to implement one
method?


b) “The class using the interface will want to cast that interface to
other interface or class types.”

In what situations would you need to cast that interface to other
interface ( or class ) and thus would choose interface over delegate
for that reason alone?


c) “The method being implemented is linked to the type or identity of
the class: for example, comparison methods. “

Are they implying that the reason for implementing IComparable
interface, you basically identify a class to the world as having
comparison methods? Or is the above quote implying something
completely different?


3)
Continuing with msdn article:

“One good example of using a single-method interface instead of a
delegate is IComparable Although using a delegate comparison method as
the basis of a sort algorithm would be valid, it is not ideal. Because
the ability to compare belongs to the class and the comparison
algorithm does not change at run time, a single-method interface is
ideal.”


a) “Because the ability to compare belongs to a class…” --> point they
are trying to make? So what if the ability belongs to a class? Why
would that make delegate less appropriate?

b) “…and the comparison algorithm does not change at run time, a
single-method interface is ideal.”

What has comparison algorithm not changing at run time got to do with
delegates and interfaces?

And besides, what do they mean with comparison algorithm not changing
at run time?


thank you
 
Ad

Advertisements

B

beginwithl

hi

Questions are great.  Don't be sorry.  :)






Yes.  You can't implement an interface with a static class.  You could  
implement an interface and then call a static method from the  
implementation, but then you're not really encapsulating the static method  
itself, IMHO.



I can't speak for the author, but I'd guess they mean any class that  
_implements_ the method.  That is, if you have a situation where the class  
is _always_ going to use some specific, single implementation for the  
method, then designing around that with an interface makes more sense.  On  
the other hand, if the class has multiple implementations to choose from, 
using each at different times according to different input, then a  
delegate would be more appropriate.


No, that's not what they are talking about.  They are talking about having  
multiple methods with the same exact signature (but not the same name),  
each of which implements some specific functionality in a different way.

For example, when sorting a collection, you may sometimes want to sort in 
ascending order and sometimes in descending order.  One easy way to do  
this is to provide two comparer methods, one that returns the "normal"  
comparison (i.e. returns -1 with the compared-to field/object is  
"greater") and another that returns the "reversed" comparison (i.e.  
returns -1 when the compared-to field/object is "less").


Because when implementing an interface, only one method can implement one> member of the interface, whereas with a delegate you can specify the  
implementation at run-time arbitrarily.

I don’t quite understand what you are saying here. I realize only one
method can implement one member of the interface, but:

Say an object O has methods A, B and C ( all having same signature ),
and delegate instance D will call one of those methods depending on
some input information. Now if we decide ( based on some input
information ) that C should be called by D, then we must register C
with D and when the time comes, D will be invoked and C will be
called:

D = O.C; // registering C with a delegate
D(); // invoking a delegate


Now if object O instead implements an interface I, which has members
A, B and C ( all with same signature ) and we again want to call one
of these methods ( based on some input data ) and if we again decide
we want to call C, then interface reference variable IR to object O
will call C at runtime with code:

IR.C(); // calling C method



As far as I can see, in both cases there had to be equal amount of
work to be done, so I’m not quite sure how delegate seems like a
better idea?!

I’m probably missing a point due to not being quite sure what you
meant with “with a delegate you can specify the implementation at
run-time arbitrarily.” ?!
I know that calls to event handlers are resolved at run time, but same
is with interfaces.
But I guess you are implying that with delegates you are able to
somehow specify at run time what method should be registered with
delegate object D? And if that is the case, then at compile time there
isn’t actually any code registering C with D, but that rather happens
at run time ( an example – say a program is already running and you
( user ) still aren’t sure which of the methods ( A, B or C ) you
should register with D. But 10 minutes into program running you
finally decide ( for whatever reason ) that method C should be
registered and thus you somehow ( during an execution of a program )
register C with D )?

* I also assume, that same can’t be done with interfaces? If so, why
not?
See above.



My personal preference would be to not cast interfaces to other types  
(interface or otherwise).  In general, if you're using an interface, you  
should care only about that interface and nothing else.

But nothing's perfect and sometimes you want to be able to pass a  
reference around, treating it as one type sometimes, but being able to  
expand on that or get another interface from it other times.  A delegate  
simply doesn't support that type of operation directly (you can look at  
the Target property for an element in a delegate's invocation list, but  
that's definitely awkward).



Well, implementing IComparable does do what you suggest.  But I think the  
advice on MSDN goes farther than that.  They are saying that the interface  
describes something intrinsic to the type.  Using IComparable as an  
example, a type would implement that if there is a single, natural way to 
order instances of the type.  Or consider IEnumerable, which a type would  
implement if there is a single, natural way to retrieve individual  
elements from the type (i.e. it's a collection).

Even for those interfaces, there are in fact often "alternate"  
implementations one might choose from for specific reasons.  Thus we have  
the IComparer interface, and all the stuff in LINQ to rearrange, filter,  
etc. collections.  But even accounting for those examples, types  
implementing IComparable and IEnumerable (for example) still have an  
obvious default behavior for those interfaces, and so they implement them..

Other types are not naturally comparable; any time you want to create an  
ordered collection of them, you want to choose specifically how to order  
them, and each time you might choose differently.  So in those cases it 
makes more sense to provide for the code wanting to specify the order to  
pass a delegate that does the comparison, or implement a _different_ class  
that implements IComparer to do the work.




Because it's combined with the second half of that clause...



Because that makes it intrinsic to the class.

God I’m dumb. I can’t get my head around the whole concept of
algorithm not changing at run time and how that makes it intrinsic to
the class. Only explanation my pee brain can think of is that if
algorithm doesn’t change at run time it must mean that is due to the
fact that for this type of objects there is only single, natural way
to order them.
But then I could argue that even with not naturally comparable types
the sorting algorithm could be implemented at compile time and not
changing at run time ( why would you even decide to change the
algorithm at run time?! ) – so my little assumption is probably way
off ... uh


again, thank you and sorry for all the troubles
 
B

beginwithl

hi

I apologize for replying so late, but I was more or less absent for
the last couple of days. Hopefully, it's not too late!




[...]
d) In any case, I don¡¦t understand how needing more than one method
implementation qualifies a delegate as being more appropriate?
Because when implementing an interface, only one method can implement
one member of the interface, whereas with a delegate you can specify
the
implementation at run-time arbitrarily.
I don¡¦t quite understand what you are saying here. I realize only one
method can implement one member of the interface, but:
Say an object O has methods A, B and C ( all having same signature ),
and delegate instance D will call one of those methods depending on
some input information. Now if we decide ( based on some input
information ) that C should be called by D, then we must register C
with D and when the time comes, D will be invoked and C will be
called:
D = O.C; // registering C with a delegate
D(); // invoking a delegate
Now if object O instead implements an interface I, which has members
A, B and C ( all with same signature ) and we again want to call one
of these methods ( based on some input data ) and if we again decide
we want to call C, then interface reference variable IR to object O
will call C at runtime with code:
IR.C(); // calling C method

The point is that the interface "IR" doesn't contain the methods A, B, and
C. It contains a _single_ method, and so a type can implement the
interface with only one method. Your example is flawed because you seem
to be assuming that the methods A, B, and C are all declared as part of
the interface. But in the relevant example, they wouldn't be.

a) I assume your argument with regards as to why interface containing
three methods ( A, B and C ) is not relevant in this debate is due to
polymorphism, meaning if we want to implement polymorphic behavior for
a given type, then we need to call all three methods with same code?


b) But if we add another level of abstraction ( the way you did with
wrapping delegates inside ¡¥CurrentDelegate¡¦ property ), then we can
decide at runtime ( via ¡¥callAppropriateMethod()¡¦ „³ see below for the
code ) which of the three methods to call?!



A relevant example would look more like this:

interface IA
{
void Method1();
}

class A : IA
{
void IA.Method1() { Console.WriteLine("IA.Method1"); }
}

versus:

delegate void Func();

class A
{
public Func CurrentDelegate
{
get
{
switch (DateTime.Now.DayOfWeek)
{
case DayOfWeek.Monday:
return new Func(MethodA);
case DayOfWeek.Wednesday:
return new Func(MethodB);
default:
return new Func(MethodC);
}
}
}

private void MethodA() { Console.WriteLine("MethodA"); }
private void MethodB() { Console.WriteLine("MethodB"); }
private void MethodC() { Console.WriteLine("MethodC"); }
}

In the first example, you can access the method only via the interface
itself, and it will always be the method declared in the class as the
implementation of the method declared in the interface:

IA ia = new A();

ia.Method1();

In the second example, you can access the method only via a property that
returns a delegate based on the current day of the week. On Mondays, you
get MethodA, Wednesdays you get MethodB, and every other day you get
MethodC. There's a single identifier to refer to in order to get and
execute the method, but the actual method that is executed depends on some
run-time logic:

A a = new A();

a.CurrentDelegate();



I'm hoping that my example above helps explain the point you're missing.
:)


What "same is with interfaces"? Calls to interfaces are only resolved at
run-time inasmuch as the compiler cannot resolve the exact method to
execute. But for any given type, the exact method that will execute when
a method in an interface implemented by that type is in fact known at
compile time.

That is, the polymorphism
implemented using an interface is determined for a given type at compile
time, whereas the polymorphism implemented using a delegate can vary in
behavior at run time according to any arbitrary logic the class providing
the delegate wants to implement.


a) So in essence the main difference is that with interfaces we must
know at compile time what method will be called for a given type, but
with delegates we are able to decide at run time what method of a
given type to call?
Or to put it differently: while with interfaces it is decided at run
time the method of which type will be run, delegates on the other hand
enable us to decide at run time which method of given type will be
run?


BTW - For the sake of simplicity I will call polymorphic behavior
with regards to deciding at run time the method of which type to call
the ¡¥class level polymorphism¡¦, while I will call the polymorphic
behavior with regards to deciding at run time which method of a given
type to call ¡¥member level polymorphism¡¦


b) And problem with interfaces is that there is no way to create at
run time calls O.A() or O.C() or O.B(); thus there is no way to
implement members level polymorphism?


c) But if your code implementing delegates allows us to decide at run
time what method of given type to call, then why couldn¡¦t the
following code also do the same with interfaces:


interface IA
{
void callAppropriateMethod( some_parameter_list)
void MethodA();
void MethodB();
void MethodC();
}


class A: IA
{
public void callAppropriateMethod ( some_parameter_list )
{
/*some code*/
¡K

switch (DateTime.Now.DayOfWeek)
{
case DayOfWeek.Monday:
this.A(); break;
case DayOfWeek.Wednesday:
this.B(); break;
default:
this.C(); break;
}
}

public void MethodA() { Console.WriteLine("MethodA"); }
public void MethodB() { Console.WriteLine("MethodB"); }
public void MethodC() { Console.WriteLine("MethodC"); }
}

IA ia = new A();
ia. callAppropriateMethod ( some_arguments );



I hope I'm stating it more strongly than just by implication. :)


It's even more flexible than that. Every single time you initialize a
variable of delegate type D, you can use any method to create the delegate
instance that matches the signature declared for the delegate type.


Because the choice of what method of a class will be used to implement a
method declared in an interface that is implemented by that class has to
be made before the code is compiled. There is no way at run time to
change that choice. Once the code is compiled, executing the method of
the interface using an instance of that class will always execute that one
method chosen before the code was compiled.


Point of order: just because you aren't understanding something, that
doesn't mean you're dumb or have a "pee brain" (which I take to be even
more derogatory than having a "pea brain" :) ).

Nah, I meant pea
In some cases, it's just because the something you're trying to understand
is so different from what you're used to that it will take some more
experience before you "get it" (and in fact, that experience may well come
from you simply trying different approaches...in this case, trying things
with both interfaces and delegates and learning from that experience how
they contrast). In many cases, your failure to understand is as much a
failure of the person trying to explain it as anything else. :)
Your explanations are great, so...
Well, as I mentioned before, one reason to use a different comparison
algorithm at run time depending on some condition would be if you wanted
to change the order of sorting. For example, ascending versus
descending. You could create a method like this:


Ah, so if we want to specify at run time which comparison algorithm to
run ( assuming an object of given type offers various comparison
algorithms ) and if we at the same time want that the same piece of
code will be able to call the appropriate algorithm, then we basically
want to implement ¡¥member level polymorphism¡¦, which delegates offer
but not interfaces?




One final question: - Interfaces enable dynamic dispatch ( a call to a
method is resolved at run time ) only with virtual instance members,
while delegates enable dynamic dispatch for static members also?


many thanx
 
B

beginwithl

hi

I've already taken too much of your time, so I will do my best to wrap
it up as quickly as possible

I apologize for replying so late, but I was more or less absent for
the last couple of days. Hopefully, it's not too late!

I think as long as you quote the relevant text to which you're replying,  
it's never too late.  :)
[...]
a) I assume your argument with regards as to why interface containing
three methods ( A, B and C ) is not relevant in this debate is due to
polymorphism, meaning if we want to implement polymorphic behavior for
a given type, then we need  to call all three methods with same code?

No, the reason that an interface with three methods is not relevant is  
that a three-method interface is different from the single-method  
characteristic of a delegate.  That is, with a three-method interface, any  
code with a reference to an implementor of that interface has access to  
all three methods.  With a delegate, the code creating the delegate  
decides which method is accessible, and only that method is accessible.

a) By accessible you mean directly accessible by an outside code?
So only reason for our interface ( one having three methods ) being
irrelevant is because of outside code ( with a reference to
implementor ) having a direct access to all three methods?

b) And that is bad coding ( in the context of Interfaces VS
delegates ) due to security reasons, lack of encapsulation or…?

c) Is that the sole reason? But to me at least, one major benefit the
delegate offered ( compared to three method interface ) was the
ability to implement polymorphic behavior for a given type --> thus
giving us member level polymorphism?!


b) But if we add another level of abstraction ( the way you did with
wrapping delegates inside ‘CurrentDelegate’ property ), then we can
decide at runtime ( via ‘callAppropriateMethod()’ see below for the
code ) which of the three methods to call?!

Delegates allow that, yes.  Interfaces don't, not really.
[...]
a) So in essence the main difference is that with interfaces we must
know at compile time what method will be called for a given type, but
with delegates we are able to decide at run time what method of a
given type to call?
Or to put it differently: while with interfaces it is decided at run
time the method of which type will be run, delegates on the other hand
enable us to decide at run time which method of given type will be
run?

Correct.  With interfaces, you can select what method to call at run-time  
as well, but _only_ by changing the implementor of the interface that  
you're using.  With delegates, a single type can provide multiple  
implementations for the same delegate.

Of course, in practice, for a given delegate, a given type is usually only  
going to provide just one implementation.  Delegates are often just used  
as a sort of short-hand for producing the same behavior one could by  
implementing single-method interfaces.  For example, the second exampleI  
gave could be implemented with interfaces like this:

     interface IA
     {
         void Method1();
     }

     class A
     {
         class AA : IA
         {
             private A _a;

             public AA(A a)
             {
                 _a = a;
             }

             public Method1()
             {
                 _a.MethodA();
             }
         }

         class AB : IA
         {
             private A _a;

             public AB(A a)
             {
                 _a = a;
             }

             public Method1()
             {
                 _a.MethodB();
             }
         }

         class AC : IA
         {
             private A _a;

             public AC(A a)
             {
                 _a = a;
             }

             public Method1()
             {
                 _a.MethodC();
             }
         }

         public IA CurrentDelegate
         {
             get
             {
                 switch (DateTime.Now.DayOfWeek)
                 {
                 case DayOfWeek.Monday:
                     return new AA(this);
                 case DayOfWeek.Wednesday:
                     return new AB(this);
                 default:
                     return new AC(this);
                 }
             }
         }

         private void MethodA() { Console.WriteLine("MethodA");}
         private void MethodB() { Console.WriteLine("MethodB");}
         private void MethodC() { Console.WriteLine("MethodC");}
     }

I know the above code is a lot more verbose compared to delegate
example, but doesn’t the above code allow us to decide at run time
what method to call – thus compiler doesn’t know what method will be
called for a given type, instead the method to call is resolved at run
time?
If that is the case, then couldn’t we argue that with interfaces too
the decision of what method ( algorithm ) to call can be decided at
run time ( via correct implementation ) – granted, they don’t offer us
member level polymorphism ( at least at the most outer level ), the
code is more verbose …?!
No way?  That's not exactly true.  After all, the implementor of the  
interface could itself do things conditionally, or with a delegate  
internally.  But at the outer-most level of the implementor,  
yes..."members level polymorphism" isn't possible.



Well, right here is the problem.  You have declared an interface with  
_four_ different methods, when all you care about is one.  The user of  
this interface could override the intended behavior simply by calling one 
of the last three methods directly.

So it all comes down to accessibility of the interface methods?
This particular interface also has the problem that it knows too much  
about the implementation.  I realize it's just for your example, but  
assuming any real-world code that looked anything like that, I would call 
for a redesign of the interface so that the interface didn't leak  
implementation details like that.
Could you elaborate a bit on that? Many interfaces define several
members, so why is mine too telling?

[...]
Ah, so if we want to specify at run time which comparison algorithm to
run ( assuming an object of given type offers various comparison
algorithms ) and if we at the same time want that the same piece of
code will be able to call the appropriate algorithm, then we basically
want to implement ‘member level polymorphism’, which delegates offer
but not interfaces?

Delegates offer it in a much more concise way, yes.  Of course, .NET  
offers the IComparer interface as a way to provide interface-based ways to  
provide alternate comparisons.  It's not an either/or thing.
One final question: - Interfaces enable dynamic dispatch ( a call to a
method is resolved at run time )  only with virtual instance members,
while delegates enable dynamic dispatch for static members also?

Yes...you can assign static methods to delegates, but interfaces must be  
instance methods.

Pete

So it all boils down to this ( I realize I’m being very repetitive in
this post … sorry about that ) :
if we want to implement several methods, where all represent similar
behavior and thus we will always have to choose between them
( depending on some condition ), then we should implement delegates
for the simple fact that that way users can’t call methods directly
( assuming we declare methods as private ) and alter the behavior,
while due to public nature of interfaces, that isn’t possible or it
is, but at the expense of code getting too verbose ?



BTW – Base class library has numerous well known interfaces defined
( like IEnumerable, IComparable ). It is common knowledge that if one
implements a well known interface, some already existing code ( like
foreach statement, or some special classes ) will be able to do some
operations on a class implementing the interface.

Is there also something similar with delegates, in a sense that there
exists some well known delegate, with which if you register your
methods, some special code will do some operation on a class that
registered event handlers with a delegate instance … ?


cheers mate
 
B

beginwithl

hi

[...]
a) By accessible you mean directly accessible by an outside code?

Yes. And my apologies if using the word "accessible" confuses the issue
with the question of public/private/etc. Obviously if the method used for
the delegate is pubilc, it's already accessible anyway. But often it will
be private, and accessible to outside code only if the class creates a
delegate and passes it outside the class.
So only reason for our interface ( one having three methods ) being
irrelevant is because of outside code ( with a reference to
implementor ) having a direct access to all three methods?

Yes, to some extent. That is, because of that, it's not a comparable
situation and so the example with a three-method interface doesn't really
address the same design problem that a delegate would.
b) And that is bad coding ( in the context of Interfaces VS
delegates ) due to security reasons, lack of encapsulation or…?

To me, "security" has a specific meaning in .NET and isn't related to this
question at all. "Security" is how you protect data, and there's not
actually anything you can do using just class design to provide for that
(reflection can always be used to bypass the language-based protections).

But lack of encapsulation? Yes. A delegate (or even a single-method
interface for that matter) would be used to allow a class to encapsulate
some behavior in a way that hides the implementation from the caller. If
you have a three-method interface that some outside code uses, then that
outside code needs to be aware of the logic that would switch between
those methods.

Of course, in some situations that might be appropriate. But then, in
those situations you wouldn't be using a delegate. In the situations when
you _would_ be using a delegate, a three-method interface would then be
inappropriate.
c) Is that the sole reason? But to me at least, one major benefit the
delegate offered ( compared to three method interface ) was the
ability to implement polymorphic behavior for a given type --> thus
giving us member level polymorphism?!

I see those benefits as one and the same. So as far as that goes, I see
no contradiction.

But I wouldn't go so far as to suggest that's the _sole_ reason. One
other nice behavior delegates give us, due to being multi-cast, is their
support for the event model in C#. Without a multi-cast delegate, the
code would have to keep track of all the subscribers in some sort of
collection. In fact, assuming we use the event model frequently enough,
it's likely that without multi-cast delegates, most code bases would wind
up re-inventing the multi-cast delegate anyway.
[...]
I know the above code is a lot more verbose compared to delegate
example, but doesn’t the above code allow us to decide at run time
what method to call – thus compiler doesn’t know what method will be
called for a given type, instead the method to call is resolved at run
time?

Sure, that was my point in showing it. Using interfaces, we accomplish
the exact same behavior that a delegate does. It's IMHO a good
illustration of how delegates are sort of like a single-method interface,
in a nice much more concise way.
If that is the case, then couldn’t we argue that with interfaces too
the decision of what method ( algorithm ) to call can be decided at
run time ( via correct implementation ) – granted, they don’t offerus
member level polymorphism ( at least at the most outer level ), the
code is more verbose …?!

I suppose that depends on what you're looking at. A single interface
implementation by itself does not offer that functionality, no.

Well, it does if an interface has several ( three in our example )
methods declared. I realize all the drawbacks you’ve described and
that it doesn’t apply to this particular situation, but still, if one
is forced to use it instead of a delegate, same functionality and
member level polymorphism ( at the outer most level ) could be
achieved using single interface implementation. I’m not saying I will
ever do it, but still ...



That's my
point. But sure, as I demonstrated, if you are willing to provide
multiple implementations of the same interface, you can accomplish the
same behavior offered by a delegate (albeit in the more verbose way).
[...]
Well, right here is the problem. You have declared an interface with
_four_ different methods, when all you care about is one. The user of
this interface could override the intended behavior simply by calling
one
of the last three methods directly.
So it all comes down to accessibility of the interface methods?

All? That might be going too far. But yes, in the context of these
examples, that's the main issue. To accomplish the same basic behavior
with a single implementor of the interface, the code implementing the
interface needs to either include the switching logic in the one method
that's called, or expose all possible methods to call and have the caller
of the interface incorporate the switching logic, thereby exposing the
implementation.

With a delegate, the switching logic can be executed once, and then from
that time on the delegate incorporates that decision inherently in a
polymorphic way.


I’m not sure what you mean by “ With delegate, the switching logic can
be executed once, and …”? For example:

delegate void Func();
class A
{
public Func CurrentDelegate
{
get
{
switch (DateTime.Now.DayOfWeek)
{
case DayOfWeek.Monday:
return new Func(MethodA);
case DayOfWeek.Wednesday:
return new Func(MethodB);
default:
return new Func(MethodC);
}
}
}
private void MethodA() { Console.WriteLine("MethodA"); }
private void MethodB() { Console.WriteLine("MethodB"); }
private void MethodC() { Console.WriteLine("MethodC"); }
}

As far as I understand, each time you try to call one of the three
methods via CurrentDelegate property, the switching logic is executed…
thus not just once, but each time the call is made.

Because the multiple methods exist not to implement different behaviors of
the interface, but instead to implement a _single_ behavior of the
interface in multiple ways.

* So multiple methods should only exist in an interface, if we use
them to implement different behaviors of the interface?!

* But I thought that interface should usually represent just one
behavior, and each of the methods declared by this interface should in
some way be one of the components of that particular behavior?



Ideally, the interface should describe what an object can _do_, not _how_
it does it. Your three-method interface does the latter, not the former.


I'm not really sure that's a fair summation of the use of delegates.
After all, I would say that the most common uses of delegates don't
involve implementations that do in fact vary at run-time. Function
callbacks, event handlers, predicate methods, etc. all very often involve
for a given section of code always the same method being called. But even
in those cases, where one could have instead declared and implemented an
interface, the delegate provides for the same basic polymorphic behavior
in a much more concise way.

In fact, I would say that the two major benefits of delegates are that
they provide the multi-cast behavior, and they provide the effect of a
single-method interface in that much more concise way. They have other
advantages as well, but I think those other advantages come up much less
frequently.



Sure, there are lots of examples in .NET that use delegates as a
fundamental aspect of their operation. The event model is a major
example. But there are many other examples. Collection filtering or
sorting has always used delegate predicates, and LINQ (in .NET 3.5) relies
heavily on delegates. The most usable asynchronous i/o model uses
delegates for the callbacks. I would say that delegates are as integral a
piece of C# and .NET as are the special interfaces you've mentioned.

I assume some of these delegates used by .Net have to be of some
specific type - meaning it isn’t enough that a delegate type has same
signature as one required by say Collection filtering or whatever, it
also has to be of some already defined and well-known delegate type?


thank you for helping me out. I really appreciate it

cheers
 
B

beginwithl

[...]
If that is the case, then couldn’t we  argue that with interfaces too
the decision of what method ( algorithm ) to call can be decided at
run time ( via correct implementation ) – granted, they don’t offer us
member level polymorphism ( at least at the most outer level ), the
code is more verbose …?!
I suppose that depends on what you're looking at.  A single interface
implementation by itself does not offer that functionality, no.
Well, it does if an interface has several ( three in our example )
methods declared.  [...]

No, an interface with three methods isn't exhibiting polymorphism.  You 
seem to be overlooking the specific _way_ in which I'm talking about  
picking a method to execute.  In plain old assembly language, you could 
always at run-time choose between multiple functions to call.  That's not  
the point.  The point is that you can _represent_ that decision as a data  
type supported in the language, providing for a form of polymorphism.


[...]
With a delegate, the switching logic can be executed once, and then from
that time on the delegate incorporates that decision inherently in a
polymorphic way.
I’m not sure what you mean by “ With delegate, the switching logic can
be executed once, and …”? For example:
     delegate void Func();
     class A
     {
         public Func CurrentDelegate
         {
             get
             {
                 switch (DateTime.Now.DayOfWeek)
                 {
                 case DayOfWeek.Monday:
                     return new Func(MethodA);
                 case DayOfWeek.Wednesday:
                     return new Func(MethodB);
                 default:
                     return new Func(MethodC);
                 }
             }
         }
         private void MethodA() { Console.WriteLine("MethodA"); }
         private void MethodB() { Console.WriteLine("MethodB"); }
         private void MethodC() { Console.WriteLine("MethodC"); }
     }
As far as I understand, each time you try to call one of the three
methods via CurrentDelegate property, the switching logic is executed…
thus not just once, but each time the call is made.

But you only need to get CurrentDelegate once.  Once you've gotten the  
delegate, you can use the delegate to invoke the chosen method over and  
over again, without needing to repeat the selection logic.


* So multiple methods should only exist in an interface, if we use
them to implement different behaviors of the interface?!

Yes, for certain definitions of "behaviors".
* But I thought that interface should usually represent just one
behavior, and each of the methods declared by this interface should in
some way be one of the components of that particular behavior?

You seem to be getting confused because you don't have a rigorous  
definition of the word "behavior".  The word will either be used to  
describe some particular operation, or it will be used to describe some  
broader sense of an object's purpose.

If used as the former, then your rule that an "interface should usually  
represent just one behavior" is simply wrong.  If used as the latter, then  
the definition you're using isn't the same as the one I'm using and so my 
statement doesn't contradict your rule.
[...]
Sure, there are lots of examples in .NET that use delegates as a
fundamental aspect of their operation.  The event model is a major
example.  But there are many other examples.  Collection filteringor
sorting has always used delegate predicates, and LINQ (in .NET 3.5)  
relies
heavily on delegates.  The most usable asynchronous i/o model uses
delegates for the callbacks.  I would say that delegates are as  
integral a
piece of C# and .NET as are the special interfaces you've mentioned.
I assume some of these delegates used by .Net have to be of some
specific type - meaning it isn’t enough that a delegate type has same
signature as one required by say Collection filtering  or whatever, it
also has to be of some already defined and well-known  delegate type?

When a specific delegate type is required, then yes...you have to use a  
delegate of that type, at least if you want to keep the code simple.  
There are ways to extract the useful information from one delegate and  
create a new one from that of a different type but the same signature.  
But it's likely that if a person found themselves wanting to do that, they  
are doing things the hard way and really should just redesign the code  
being used so that they can do things more elegantly.

You certainly can't just assign delegates of different types to each  
other, with or without an explicit cast.  Each delegate type is distinct  
and incompatible with any other delegate type.

Normally it doesn't matter at all, because you aren't copying delegates,  
you're just creating new ones from method names.

Pete
 
Ad

Advertisements

B

beginwithl

hi Pete

Sorry for keep dragging on this thread

[...]
If that is the case, then couldn¡¦t we argue that with interfaces too
the decision of what method ( algorithm ) to call can be decided at
run time ( via correct implementation ) ¡V granted, they don¡¦t offer us
member level polymorphism ( at least at the most outer level ), the
code is more verbose ¡K?!
I suppose that depends on what you're looking at. A single interface
implementation by itself does not offer that functionality, no.
Well, it does if an interface has several ( three in our example )
methods declared. [...]

No, an interface with three methods isn't exhibiting polymorphism. You
seem to be overlooking the specific _way_ in which I'm talking about
picking a method to execute. In plain old assembly language, you could
always at run-time choose between multiple functions to call. That's not
the point. The point is that you can _represent_ that decision as a data
type supported in the language, providing for a form of polymorphism.
Uhm, I do understand that delegates enable member level polymorphism,
while that is not the case with interfaces. I was just implying that
if you correctly implement an interface with several methods ( where
you always have to choose between one of those methods ), your code
may at the most-outer level offers some sort of member-level-
polymorphism.
Thus delegate types offer us member level polymorphism, while
interfaces don¡¦t, but we can also achieve member level polymorphism if
we implement interfaces, but even then interfaces don¡¦t have member
level polymorphic behavior/ability, but the code ( one implementing
that interface ) as a whole does offer some sort of member level
polymorphism.



[...]
With a delegate, the switching logic can be executed once, and then from
that time on the delegate incorporates that decision inherently in a
polymorphic way.
I¡¦m not sure what you mean by ¡§ With delegate, the switching logic can
be executed once, and ¡K¡¨? For example:
delegate void Func();
class A
{
public Func CurrentDelegate
{
get
{
switch (DateTime.Now.DayOfWeek)
{
case DayOfWeek.Monday:
return new Func(MethodA);
case DayOfWeek.Wednesday:
return new Func(MethodB);
default:
return new Func(MethodC);
}
}
}
private void MethodA() { Console.WriteLine("MethodA"); }
private void MethodB() { Console.WriteLine("MethodB"); }
private void MethodC() { Console.WriteLine("MethodC"); }
}
As far as I understand, each time you try to call one of the three
methods via CurrentDelegate property, the switching logic is executed¡K
thus not just once, but each time the call is made.

But you only need to get CurrentDelegate once. Once you've gotten the
delegate, you can use the delegate to invoke the chosen method over and
over again, without needing to repeat the selection logic.

* Let us assume it is Monday:

delegate void Func();

class A
{
public Func CurrentDelegate
{
get
{
switch (DateTime.Now.DayOfWeek)
{
case DayOfWeek.Monday:
return new Func(MethodA);
case DayOfWeek.Wednesday:
return new Func(MethodB);
default:
return new Func(MethodC);
}
}
}

private void MethodA() { Console.WriteLine("MethodA"); }
private void MethodB() { Console.WriteLine("MethodB"); }
private void MethodC() { Console.WriteLine("MethodC"); }
}


A a = new A();
Func func = a. CurrentDelegate;

Statement ¡§ Func func = a. CurrentDelegate; ¡¨ will create a delegate
instance with ¡¥MethodA()¡¦ in its invocation list.. Now whenever we
want to call this event handler, we just have to write

func();

without the need to call ¡§CurrentDelegate¡¨ property „³ now ifour
program is still running when Monday shifts to Tuesday, then delegate
should invoke ¡§MethodB()¡¨ instead. For this reason we again needto
call ¡§CurrentDelegate¡¨ property, so that ¡§MethodA()¡¨ is replaced
with ¡§MethodB()¡¨ in the invocation list. And by calling
¡§CurrentDelegate¡¨ property, the switching logic is executed for the
second time:

func = a.CurrentDelegate;
func(); // now whenever we invoke the delegate, MethodB() will be
called



* Let¡¦s again assume it is Monday:

interface IA
{
void Method1();
}
class A
{
class AA : IA
{
private A _a;
public AA(A a)
{
_a = a;
}
public Method1()
{
_a.MethodA();
}
}
class AB : IA
{
private A _a;
public AB(A a)
{
_a = a;
}
public Method1()
{
_a.MethodB();
}
}
class AC : IA
{
private A _a;
public AC(A a)
{
_a = a;
}
public Method1()
{
_a.MethodC();
}
}
public IA CurrentDelegate
{
get
{
switch (DateTime.Now.DayOfWeek)
{
case DayOfWeek.Monday:
return new AA(this);
case DayOfWeek.Wednesday:
return new AB(this);
default:
return new AC(this);
}
}
}
private void MethodA() { Console.WriteLine("MethodA"); }
private void MethodB() { Console.WriteLine("MethodB"); }
private void MethodC() { Console.WriteLine("MethodC"); }
}

A a = new A();
IA ia = a. CurrentDelegate;

Statement ¡§ IA ia = a. CurrentDelegate; ¡¨ will return to ¡§ia¡¨ variable
a reference to object of type ¡§AA¡¨, which in turn implements ¡§Method1
()¡¨ that whenever invoked, calls ¡§MethodA()¡¨ contained in instance of
type ¡§A¡¨.

Now whenever we execute the following statement:

ia.Method1();

¡§MethodA()¡¨ is called and thus we don¡¦t have to call ¡§CurrentDelegate¡¨
property anymore and thus we don¡¦t have to repeat the selection logic
again.

But if our program is still running when Monday turns to Tuesday, then
we must call ¡§MethodB()¡¨ instead, and for that to happen, we again
need to call ¡§CurrentDelegate¡¨ property and thus repeat the selection
logic for the second time:

A a= new A();
IA ia = a. CurrentDelegate;
ia.Method1(); // now MethodB() is invoked


* So to my understanding, in both the delegate and the interface
examples the selection logic was repeated only when we needed to
select different method. Once the method was selected, we could call
this method without needing to repeat the selection logic.




BTW ¡V in classes ¡¥AA¡¦, ¡¥AB¡¦ and ¡¥AC¡¦ you¡¦ve implemented ¡¥Method1()¡¦
without specifying the return value of void ¡V was that just a bug or
¡K:

public Method1()
{
_a.MethodC();
}
?


Yes, for certain definitions of "behaviors".


You seem to be getting confused because you don't have a rigorous
definition of the word "behavior". The word will either be used to
describe some particular operation, or it will be used to describe some
broader sense of an object's purpose.

If used as the former, then your rule that an "interface should usually
represent just one behavior" is simply wrong. If used as the latter, then
the definition you're using isn't the same as the one I'm using and so my
statement doesn't contradict your rule.

* So if word behavior describes some particular operation, then
"interface should usually represent just one behavior" claim is
wrong. And as such, a single interface can describe many operations?

* What about sorting, for example? Couldn¡¦t we claim that interface
( which declares various sorting algorithms ) describes just a single
behavior?
And as you¡¦ve said it yourself, ¡§interface should describe what an
object can _do_, not _how_ it does it. ¡¨.

In other words, I interpret an interface declaring multiple methods
( each representing a different sorting algorithm ) as describing
¡§how_object_does_it¡¨, which is a bad design?!


thank you
 
B

beginwithl

hi
[...]
* So if word behavior describes some particular operation, then
"interface should usually   represent just one behavior" claim is
wrong. And as such, a single interface can describe many operations?
Yes.

* What about sorting, for example? Couldn’t we claim that interface
( which declares various sorting algorithms ) describes just a single  
behavior?
And as you’ve said it yourself,  “interface should describe what an
object can _do_, not _how_   it does it. ”.
In other words, I interpret an interface declaring multiple methods
( each representing a different sorting algorithm ) as describing
“how_object_does_it”, which is a bad design?!

Yes.  A correct design would provide a single interface that "sorts" and  
then have a different implementation of the interface for each way to  
sort.  Or, provide for the use of a delegate to specify the way to sort..  
.NET provides for both variations on that theme, with Comparison<T> and  
IComparer<T>.


I haven’t looked at Comparison<T> and Comparer<T>, but I assume they
implement a specific kind of sorting algorithm based on a type of T?

thanx mate
 
B

beginwithl

Ah, so a design would be similar to the way you wrote our interface
example, where interface member Method1() called one of private class
methods ( MethodA, MethodB or MethodC ). Thus, a class implementing
sorting interface would implement private methods ( each representing
different sorting algorithm ) and we would choose ( using some
selection logic ) one of these sorting algorithms via single interface
method?!
 
B

beginwithl

hi


Using interfaces, you choose from the _implementing class_, rather than  
the method itself.  So I'd say that saying literally "we choose...via  
single interface method" isn't correct.  We choose via the interface  
implementation itself, which brings along with it a specific method or  
methods.

For interfaces that have more than one method, this is often in fact the  
most efficient way to manage it.  But for interfaces with only one method,  
as my example shows, that is a very verbose way of doing the exact same  
thing a delegate provides.

Hence, one example of why the concept of a delegate is useful.  :)

Of course, there are times when a single-method interface makes sense.  
Just because you're only dealing with one method to call at a time, that  
doesn't mean a delegate is more appropriate than an interface.  It just 
depends on how you're going to use the types and the method.

Pete

I'm wondering how many million miles of code I will have to write to
see ( understand ) the design concepts as clearly in my mind as you
do?! :(

*sheds a tear*


I know I'm repeating myself, but I'm truly grateful for your kind
help. You've really helped a lot

cheers mate
 
Ad

Advertisements

I

ian.warburton3000

Great discussion guys!

I just wanted to add my own thoughts...

It seems to me that regardless of whether one uses delegate
polymorphism or class polymorphism one can end up with exactly the
same run time result. So I reckon one way to choose between the two
features is to ask one's self, 'how do I want to organise my methods?'

Do I want my different method implementations filed away neatly in an
inheritance hierarchy or do I want my method implementations scattered
all over the place in unrelated classes?

So if I just wanted to plug in a sort handler for a LINQ query, I
might just define the method in-line. But if I want multiple versions
of a multi method interface then it would be cleaner and better
organised to structure them in an inheritance hierarchy.

Any thoughts?
 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top