views:

173

answers:

4

Hi All,

I have some classes inherit from existing Windows Controls like TextBox and DateTimePicker, ..etc

I want to add custom functionalities for these classes like (Read, Alert, ...etc) these added functionalities are the same in all these classes

The problem is: these classes inherited from difference parents so I can't put my added functionalities in the parent class,

What's the best practice in this case:

  • repeat the code in each inherited class

  • Use a separated class have the functionalities as Static Methods with parameter from an interface, implement this interface for the classes and then pass them.

  • Use a separated class like the second approach but with Dynamic parameter (which added in C# 4.0)

    or other !!

Thanks in advance

+5  A: 

Use Composition instead of Inheritence!

Justin Niessner
Not an answer to the question, but a good piece of advise! +1
bloparod
+1  A: 

If you must, what I would probably do is create extension methods for each class and then reference the actual coded needed for these in some other object all the extension methods can call.

This way the code isn't duplicated, and the extension methods make it look like the methods should be in the object.

It's the same essentially by creating a static method and doing: Functions.DoSomething(my_Object);

But I always like: my_Object.DoSomething() better in an OO language.

Kevin
+11  A: 

I'd consider option 4: composition.

First, define your set of functionality. We'll assume that your partial list is exclusive, so "Read" and "Alert."

Second, create a single class that implements this functionality, something like MyCommonControlBehaviors. I'd prefer this implementation not be static if possible, though, it may be generic.

public MyCommonControlBehaviors
{
    public Whatever Read() { /* ... */ }
    public void Alert() {}
}

Third, use composition to add an instance of this class to each of your custom control types and expose that functionality through your custom control:

public class MyCustomControl
{
    private MyCommonControlBehaviors common; // Composition

    public Whatever Read() { return this.common.Read(); }
    public void Alert() { this.common.Alert(); }
}

Depending on specifics, you can get creative to the degree necessary. E.g., perhaps your custom behaviors need to interact with private control data. In that case, make your control implement a common ICommonBehaviorHost interface that your common behaviors need. Then pass the control into the behavior class on construction as an instance of ICommonBehaviorHost:

public interface ICommonBehaviorHost
{
    void Notify();
}

public class MyCommonControlBehaviors
{
    ICommonBehaviorHost hst = null;

    public MyCommonControlBehaviors(ICommonBehaviorHost host) 
    {
        this.hst = host;
    }

    public void Alert() { this.hst.Notify(); }  // Calls back into the hosting control
    // ...
}

public class MyCustomControl : ICommonBehaviorHost
{
    private MyCommonControlBehaviors common = null;

    public MyCustomControl() { common = new MyCommonControlBehaviors(this); }
    public Whatever Read() { return this.common.Read(); }
    public void Alert() { this.common.Alert(); }

    void ICommonBehaviorHost.Notify() { /* called by this.common */ }
}
Greg D
and couple it with dependency injection to minimize the coupling of your system...
marc_s
+1 @marc_s for truth. There are a lot of add'l techniques that can be used to minimize coupling and and add capability to this approach. One thing that I've done in the past is make `MyCommonControlBehaviors` generic so that it can return a `MyCustomControl`, whatever that is. (In this example it doesn't make much sense, but in the domain I was working with it made a lot of sense.)
Greg D
A: 

I would suggest defining an interface for the behaviors, and then (to keep from repeating yourself) create extension methods on that interface definition for your shared methods. (Kinda like your second option, only with extension methods instead of totally static methods).

ckramer