Code Novice
Code Novice

Reputation: 2398

How to update class code to make it Type Independent

Problem: I currently have a class that takes in an object of type Control and does some work. I'm attempting to create a class that can take in either a Control, Button or a Label object. I can make this work however it would involve that I copy and paste the class two more times. One to work with Buttons and another to work with Labels. The logic and the members being called are exactly the same with the exception of the Type. I have simplified the concept I'm wishing to convey below:

// This class currently only does work on a Control object
public class takeControlType
{
    public takeControlType(Control control)
    {
        string objectName = control.Name.ToString();
    }
}

I could copy paste the code above and make it work by overloading the class Constructor like this:

public class takeAnyType
{
    public takeAnyType(Control control)
    {
        string objectName = control.Name.ToString();
    }
    public takeAnyType(Button button)
    {
        string objectName = button.Name.ToString();
    }
    public takeAnyType(Label label)
    {
        string objectName = label.Name.ToString();
    }
}

Am I correct in thinking that this just seems like a drag in productivity? I'm hoping I can reuse the same logic despite the Type being different as the only item that I would need to replace is the Type. The logic and properties being implemented in my class are exactly the same for Controls, Buttons and Labels. I've researched generics but due to the fact that I'm pulling back properties and methods specific to either a Control, Button or Label I can't seem to get generics to work with the object properties such as .Name or .Width or .Capture for example. The only methods the generic Type provides me with are

I need access to a few of the properties I mentioned previously. How does one accomplish this in order that I might avoid having to copy/paste 266 lines of code that make up my class that currently is only able to work with Control objects?

Aside from attempting to make use of Generics I also tried to see if I could use base class type object as opposed to Control but that led me to the same issue I'm currently having with Generics. I no longer have access to the members that are associated with Controls, Buttons and Labels.

To clear up any confusion the example (non-working) code below is what I'm attempting to accomplish.

public class takeAnyType
{
    public takeAnyType(anyType obj)
    {
        string objectName = obj.Name.ToString();
        obj.Cursor = Cursors.SizeNESW;
        obj.Capture = true;
        obj.Width = 20;
        obj.Top = 100;
    }
}

Upvotes: 1

Views: 219

Answers (2)

Alexei - check Codidact
Alexei - check Codidact

Reputation: 23098

An answer addresses your example, but your problem seems to describe something more - doing some more convoluted login on Labels and Buttons. One way to do this is the following:

1) declare a base class to handle common issue (e.g. your name example)

2) declare a class for each Label and Button to handle specific logic

public class ControlHelper
{
    public virtual String GetControlName(Control control)
    {
        return control.Name.ToString();
    }

    // it is not possible to do the logic on a generic control, so force derived classes to provide the logic
    public abstract void DoSomeFancyStuffWithControl(Control control);

    // other common functions may come here
}

public class LabelHelper : ControlHelper
{
    // you may override virtual methods from ControlHelper. For GetControlName, it should not be the case
    public override DoSomeFancyStuffWithControl(Control control)
    {
        var button = control as Label;
        // ...
    }

    // does not have to be virtual, but allow further inheritance
    public virtual String GetText(Label l)
    {
        return l.Text;
    }

    // other label specific methods come here
}

public class ButtonHelper : ControlHelper
{
    public override DoSomeFancyStuffWithControl(Control control)
    {
        var button = control as Button;
        // ...
    }

    public virtual bool GetEnabled(Button b)
    {
        return b.Enabled;
    }

    // other button specific functions may come here
 }

Upvotes: 0

Yacoub Massad
Yacoub Massad

Reputation: 27871

Button and Label classes inherit from Control (indirectly). This means that if you only create a class for Control, you can still use it for objects of type Button or Label. You don't have to create special classes for those.

In C# (and OO languages in general), you can assign an instance of a derived class to a variable of a super class. For example, this is valid C# code:

Control control = new Button();

Upvotes: 3

Related Questions