472,780 Members | 1,169 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,780 software developers and data experts.

How to Design Delegate Architecture ?

Hi folks

I think I have asked something similar before, but here goes again...

I have to call a method that varies depending on the type of one of its
parameters.

The object that I have to pass is of a base class.

I do not want to have an "if (...) else" construct if I can avoid it.

Example methods are :

void Method1(TextBoxBase widget)
{
}

void Method2(NumericUpDown widget)
{
}

Calling method looks like this :

void CallAppropriateMethod(Control widget)
{
...
}

I thought of adding the methods to a static class :

public static class WidgetHandler
{
public static void Method(TextBoxBase widget)
{
}

public static void Method(NumericUpDown widget)
{
}
}

....and calling them, hoping that the type would be inferred and called
appropriately.

void CallAppropriateMethod(Control widget)
{
WidgetHandler.Method(widget); // code this simple would be the best !!
}

But this, of course, involves casting a base type to a specific type; not
allowed :-((

I also thought of using delegates and retrieving a particular delegate based
on a type parameter, but I couldn't get a Dictionary<Type, MyDelegate> to
work as it meant having a return from the function that would be a "base"
delegate and that I could call without knowing the type of the parameter; so
far, no success.

Generic delegates don't seem to offer the answer as you have to know the
type of the delegate you want to invoke :-((

Am I really suffering from brain-fade on this one, or is there a method I
have simply not found yet ??

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jan 26 '06 #1
4 1375
Its not necessarily elegant, but you can do this with reflection in a
broadly acceptable way; I would prefer something neater, though:

using System;
using System.Reflection;
using System.Windows.Forms;

class Program {
private static void Main() {
WidgetHandler.CallAppropriateMethod(new TextBox());
WidgetHandler.CallAppropriateMethod(new NumericUpDown());
WidgetHandler.CallAppropriateMethod(new FlowLayoutPanel()); // don't
expect this to work
}
}

public sealed class WidgetHandler {

private WidgetHandler() { // private ctor
}
private static readonly WidgetHandler Singleton;
static WidgetHandler() {
Singleton = new WidgetHandler();
}

public static void CallAppropriateMethod(Control widget) {
if (widget == null)
throw new ArgumentNullException("widget");
Type widgetType = widget.GetType();
MethodInfo method = typeof(WidgetHandler).GetMethod("Method",
BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] {
widgetType }, null);

if (method == null)
throw new NotSupportedException("Method(" + widgetType.Name + ")
is not supported");
method.Invoke(null, new object[] { widget });
}

private static void Method(TextBoxBase widget) {
System.Diagnostics.Debug.WriteLine("I work with TextBoxBase
widgets");
}

private static void Method(NumericUpDown widget) {
System.Diagnostics.Debug.WriteLine("I work with NumericUpDown
widgets");
}
}
Jan 26 '06 #2
"Marc Gravell" <mg******@rm.com> a crit dans le message de news:
e8**************@TK2MSFTNGP12.phx.gbl...

| Its not necessarily elegant, but you can do this with reflection in a
| broadly acceptable way; I would prefer something neater, though:

Well, as you say, it's not elegant, but it certainly does the job.

Like you, I really would prefer something better, but in the meanwhile your
solution allows me to get on with something else :-)

Many thanks

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jan 26 '06 #3

Calling a different method based upon the type of the object sounds
like a good candidate for a polymorphic solution.
It would perhaps be tedious to implement but it will work and can be
extended.

Say you have 2 controls with which you want to do this

1) TextBox
2) Label
Define an interface IMyControl

public interface IMyControl
{
// Methods
void DoSomething();
}
Derive new versions of each control, implementing IMyControl

public class MyTextBox : System.Windows.Forms.TextBox, IMyControl {

...

public void DoSomething(){
// Do Something Textbox specific
}

}

public class MyLabel : System.Windows.Forms.Label, IMyControl {

...

public void DoSomething(){
// Do Something Label specific
}

}
Your selector now becomes
IControl iface;

try{

iface = (IControl) sender;
iface.DoSomething();

}
catch (System.InvalidCastException ex) {
throw new NotSupportedException("MESSAGE");
}
catch (System.Exception ex) {
// Handle exception or rethrow
}

PROS:
It is pretty easy to understand and can be extended to any number of
controls with no need of if..then or selection constructs.

CONS:
You need to generate custom versions of each control. (not that hard)
You need to replace all definitions/references to the base controls
with these new ones (can be tedious if one has an existing large
codebase)
NOTES:
If the functionality to be invoked is not accessible from within the
controls (e.g. on a form or in a separate class) then one can use a
callback setup, setting the target with static members on the derived
class
e.g.

...
public delegate void HandleSpecific();

public static void SetDelegate( HandleSpecific del) {
_handler = del;
}

private static HandleSpecific _handler;

public void DoSomething(){
_handler();
}
hth,
Alan .

Jan 26 '06 #4

"Joanna Carter [TeamB]" wrote:
Hi folks

I think I have asked something similar before, but here goes again...

I have to call a method that varies depending on the type of one of
its
parameters.

The object that I have to pass is of a base class.

I do not want to have an "if (...) else" construct if I can avoid it.

Example methods are :

void Method1(TextBoxBase widget)
{
}

void Method2(NumericUpDown widget)
{
}

Calling method looks like this :

void CallAppropriateMethod(Control widget)
{
...
}
You need double dispatch for this. Unfortunately, C# doesn't have it.

You can use Visitor instead, but it requires adding an Accept method to
the visitees. If you're using control classes from the .NET framework,
this rules that out, unless you derive a class from each control class
you're using and add the Accept method there.

<snip>
I also thought of using delegates and retrieving a particular delegate
based
on a type parameter, but I couldn't get a Dictionary<Type, MyDelegate>
to
work as it meant having a return from the function that would be a
"base"
delegate and that I could call without knowing the type of the
parameter; so
far, no success.


What I've done in a similar situation is to write a custom dispatcher
class. The class looks something like this:

public class TypeDispatcher
{
public void Dispatch(object obj)
{
if(obj is SomeType)
{
// Cast object to type and call a delegate
// or pass the casted object to a method of
// an object.
}
else if(obj is SomeOtherType)
{
// ...
}

// And so on...
}
}

You register delegates of a particular type for the object type you are
interested in. In other words, when the dispatcher finds the object's
type, it calls a preregistered delegate, passing it the object casted to
its type. You can use events instead. Or you can create interfaces for
each type and associate objects that implement the interfaces with the
dispatcher. The dispatcher will then pass along the casted object to the
interface's method for processing the object.

The nice thing about this approach is that you isolate the cascading
if/else if's to one location. It can be used any where you need
dispatching for the base type.

Hope this helps.
Jan 26 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Andy Read | last post by:
Hello all, I have the requirement to produce source code that produces an object hierarchy. Example: Root | Folder 1
15
by: Sharon | last post by:
I’m trying to build a generic Publisher-Subscriber that will work over the net, so I’m using the Remoting. I wish that the subscriber user will be notify about the messages sent by the...
2
by: Matthius | last post by:
Greetings, I am a database guys trying to get into C# and design patterns. I really like the "Head first design patterns" book but don't like that it has samples in java. Is anyone interested...
2
by: SemSem | last post by:
how to make a well design web pages and web form in ,net as all form ido is very simple iwant to improve it . if there some tools to used in .net or some techneque iheard about css or...
0
by: Joerg Rech | last post by:
Dear software practitioners, consultants, and researchers, we are currently conducting an international survey about architecture and design patterns. Our goal is to discover how familiar people...
0
by: Joerg Rech | last post by:
Dear software practitioners, consultants, and researchers, we are currently conducting an international survey about architecture and design patterns. Our goal is to discover how familiar people...
19
by: neelsmail | last post by:
Hi, I have been working on C++ for some time now, and I think I have a flair for design (which just might be only my imagination over- stretched.. :) ). So, I tried to find a design...
2
by: Tem | last post by:
I have 2 projects a classlibrary project and a windows forms project. the winform app calls the library to perform certain functions and returns the results. however i run into a problem where...
9
by: raylopez99 | last post by:
Here are two different ways of achieving a mediator pattern: the first, using circular references (for lack of a better way to describe it), but not using delegates, with the second using...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: erikbower65 | last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps: 1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal. 2. Connect to...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: erikbower65 | last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA: 1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
5
by: DJRhino | last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer) If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _ 310030356 Or 310030359 Or 310030362 Or...
0
by: lllomh | last post by:
How does React native implement an English player?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.