Fog Creek Software
Discussion Board




Welcome! and rules

Joel on Software

Object types and function overloading

... I think, my terminology could be a bit wrong, but anyway.

i have a loop that gets controls and enable/disables them based on a recordset of

ControlName (string), IsEnabled (int)

so i do:


Control c;

while(reader.Read())

{
    c = Page.FindControl(reader["Name"].ToString());
    //do enabling code
}


now, based on the type of the control I want to do different things eg set Enabled/Disabled depending on which the control uses.

I wrote a bunch of functions like this

private void DoControl(DropDownList d)
{
    d.Enabled = false;
}

private void DoControl(HTMLInputButton b)
{
    b.Disabled = true;
}

private void DoControl(Control c)
{
    //dont know, could be anything!
}


etc...

unfortunatly the control c always goes into the last of these functions.

I resorted to checking the .ToString() of the control, putting in a switch, and then casting the control to whatever i found

eg

switch(c.ToString())
{
    case "System.Web.Ui.Webcontrols.DropDownList" :
    {
        ((System.Web.Ui.Webcontrols.DropDownList)c).Enabled = false;
        break;
    }
}

clearly this is an ugly way of doing things, but I don't know any better at the moment

Does anyone have any advice?

is there a way of converting a high level object (Control) into its most "detailed" class? (As i said, not sure of the terminology)

all education gratefully received

col

Colin
Monday, March 03, 2003

Ckeck the 'is' and 'as' C# operators:

'as' is a safe cast operator,

object obj = myControl as System.Web.Ui.Webcontrols.DropDownList

if (obj != null)
{
    // code specific for System.Web.Ui.Webcontrols.DropDownList
}


On the other hand, 'is' is a boolean operator that returns true or false:

if (obj is System.Web.Ui.Webcontrols.DropDownList)
{
    // code specific for System.Web.Ui.Webcontrols.DropDownList
}

To get the 'most derived' type of a variable, you can use the GetType() method (declared in the Object class) to get an object that represents the metadata of the Type:

Type contolType = c.GetType();

And use the Type class' static GetType method to create a specific Type object to compare to:

if(contolType.Equals(Type.GetType("System.Web.Ui.Webcontrols.DropDownList"))
{
    // specific System.Web.Ui.Webcontrols.DropDownList code.
}

I would go for the 'is' check, as it seems to allow 'cleaner' code, but the GetType() approach allows to even store the type strings in the database along with your security info and make the code more generic and easy to change.

sergio acosta
Monday, March 03, 2003

I reviewed my post and thought that is better to declare a referecce of the specific type when using 'as':

System.Web.Ui.Webcontrols.DropDownList obj = myControl as System.Web.Ui.Webcontrols.DropDownList

if (obj != null)
{
    // code specific for System.Web.Ui.Webcontrols.DropDownList
}

sergio acosta
Monday, March 03, 2003

It seems to me that rather than relying on a bunch of casts, it'd be simpler to deal with the logic as either a switch statement or an if/else if/else block:

while (reader.Read())
{
    Control c = null;

    try { c = FindControl(reader["Name"].ToString()); }
    catch { }

    if (c != null)
    {
        string type = c.GetType().FullName;

        switch (type)
        {
            case "System.Web.UI.Webcontrols.DropDownList":
                c.Enabled = false;
                break;
            case "System.Web.UI.HtmlControls.HtmlInputButton":
                c.Enabled = true;
                break;
            default:
                c.Enabled = false;
                break;
        }

        // OR...

        if (c is DropDownList)
        {
            c.Enabled = false;
        }
        else if (c is HTMLInputButton)
        {
            c.Enabled = true;
        }
        else
        {
            // default
            c.Enabled = false;
        }
    }
}

John Barnette
Monday, March 03, 2003

i've done things like this before not in .net though.
I always used style sheets. You should be able to dynamically generate style sheets from your database and Apply those to the page.  "enabled" shouldn't be any different than any other property.

Micah
Monday, March 03, 2003

Why not you use interfaces for such task?

If I were you I would derive my classes from controls and implement some interface. You can use your new controls as usual. See an example:

interface IMyProcessing{
    void DoMyAction();
}

publi class MyDropDownList: DropDownList, IMyProcessing{
//.......
    public void DoMyAction(){
          this.Enabled = false;
    }
}

publi class MyHTMLInputButton: HTMLInputButton, IMyProcessing{
//.......
    public void DoMyAction(){
          this.Disabled = true;
    }
}
.......
//following is just an example. Use an appropriate code
foreach (IMyProcessing my in ControlsCollection){
    my.DoMyAction()
}

Mikhail Andronov
Wednesday, March 05, 2003

Thanks for all the replies!

The interfaces method seems to me to be the one that fits best with what I had imagined I should be able to to, call a generic method on each object.

The other ways seem to be different ways of finding out the control type and then acting on that, which is what I'm doing already.

cheers again

col

Colin
Friday, March 07, 2003

If you rely on the string name of the class, then your code will break if someone has extended that class.

For instance, "is DropDownList" will still work if someone has implemented MyDropDownList as a child class of DropDownList, but if you're testing for  type.ToString() == "DropDownList", then it won't match.

Richard Ponton
Monday, March 10, 2003

Hi - This is my first time to this site and my first .Net project so this is very basic questions I have. First of all, I couldn't see where to post a new question, thus the reason I am replying to this current topic.

Does anyone have any suggestions of good sites for tutorials or quick lookups to .Net for beginners?

Second, this was my first project on the job.

Create a vb.net project that returns the standard address info and the formatted daytime phone number on a single form from just the customer id for input. Display Messagebox error if not found. OK to hardwire the DB connection and credentials. Use menus "File | Exit".

My question is - Do I just create one form with the input box and then display boxes for the returned information? Is that the standard way?

Thanks so much!

Tracy Siegle
Tuesday, March 11, 2003

Tracey, from http://discuss.fogcreek.com/dotnetquestions/
click "Start a New Topic"

Duncan Smart
Tuesday, March 11, 2003

Actually, I think the best fit is really the Visitor pattern. This example[1] is in Java, but you should get the picture. You get by-type dispatching without using a switch statement. Personally, I think it's even more convenient and elegant to do it with reflection, but it comes at a performance penalty vs. visitor interfaces.

[1] http://ootips.org/visitor-pattern.html

Brad (dotnetguy.techieswithcats.com)
Tuesday, March 11, 2003

*  Recent Topics

*  Fog Creek Home