Re: Delegates VS interfaces - some confusion
- From: beginwithl@xxxxxxxxx
- Date: Sun, 18 Jan 2009 12:31:48 -0800 (PST)
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!
On Jan 15, 10:27 am, "Peter Duniho" <NpOeStPe...@xxxxxxxxxxxxxxxx>
wrote:
On Wed, 14 Jan 2009 18:42:25 -0800, <beginwi...@xxxxxxxxx> wrote:
[...]
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();
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'm hoping that my example above helps explain the point you're missing.
:)
I know that calls to event handlers are resolved at run time, but same
is with interfaces.
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*/
…
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 );
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?
I hope I'm stating it more strongly than just by implication. :)
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 )?
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.
* I also assume, that same can’t be done with interfaces? If so, why
not?
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.
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.
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 understandYour explanations are great, so...
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. :)
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
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
.
- Follow-Ups:
- Re: Delegates VS interfaces - some confusion
- From: Peter Duniho
- Re: Delegates VS interfaces - some confusion
- References:
- Delegates VS interfaces - some confusion
- From: beginwithl
- Re: Delegates VS interfaces - some confusion
- From: Peter Duniho
- Re: Delegates VS interfaces - some confusion
- From: beginwithl
- Re: Delegates VS interfaces - some confusion
- From: Peter Duniho
- Delegates VS interfaces - some confusion
- Prev by Date: Re: Some claim that delegates should be single-cast
- Next by Date: Re: Delegates VS interfaces - some confusion
- Previous by thread: Re: Delegates VS interfaces - some confusion
- Next by thread: Re: Delegates VS interfaces - some confusion
- Index(es):
Relevant Pages
|