473,386 Members | 1,698 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 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 1393
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...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...

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.