Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Type-cases and object oriented code don't seem to get on that well together in my experience. The approach I prefer in this situation is the <a href="http://c2.com/cgi/wiki?DoubleDispatch" rel="nofollow noreferrer">double dispatch pattern</a>. In short:</p> <ul> <li><b>Create a listener type</b> with an empty virtual method Process(ExtendedTypeN arg) for each extended type you will be dispatching over. <li><b>Add a virtual method</b> Dispatch(Listener listener) to the base type that takes a listener as argument. Its implementation will be to call listener.Process((Base) this). <li><b>Over<i>ride</i></b> the Dispatch method in each extended type to call the appropriate <b>over<i>load</i></b> of Process in the listener type. <li><b>Extend the listener type</b> by overriding the appropriate Process method for each subtype you are interested in. </ul> <p>The argument shuffling dance eliminates the narrowing cast by folding it into the call to Dispatch -- the receiver knows its exact type, and communicates it by calling back the exact overload of Process for its type. This is also a big performance win in implementations such as .NET Compact Framework, in which narrowing casts are extremely slow but virtual dispatch is fast.</p> <p>The result will be something like this:</p> <pre><code> public class Listener { public virtual void Process(Base obj) { } public virtual void Process(Derived obj) { } public virtual void Process(OtherDerived obj) { } } public class Base { public virtual void Dispatch(Listener l) { l.Process(this); } } public class Derived { public override void Dispatch(Listener l) { l.Process(this); } } public class OtherDerived { public override void Dispatch(Listener l) { l.Process(this); } } public class ExampleListener { public override void Process(Derived obj) { Console.WriteLine("I got a Derived"); } public override void Process(OtherDerived obj) { Console.WriteLine("I got an OtherDerived"); } public void ProcessCollection(IEnumerable collection) { foreach (Base obj in collection) obj.Dispatch(this); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload