Simpler way to check and call overloaded method

private void SomeMethod(DerivedA something) {...}
private void SomeMethod(DerivedB something) {...}
private void SomeMethod(DerivedC something) {...}


BaseClass bc = somevariable;
if (bc is DerivedA) Somemethod(bc as DerivedA)
else if (bc is DerivedB) Somemethod(bc as DerivedB)
else if (bc is DerivedC) Somemethod(bc as DerivedC)
...
else if (bc is DerivedZZ) Somemethod(bc as DerivedZZ)

In .NET 3.5, there has got to be a simpler way, no?

Upvotes: 0

Views: 114

Answers (4)

kev
kev

Reputation: 1124

I would also go with redesigning your classes like the others already stated but if you can't do that, you can use reflection to do the job

this.GetType().InvokeMember("SomeMethod", // Method name
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod,
    null, // DefaultBinder
    this, // object to call the method on
    new[]{ bc } // parameters to the method
    );

if SomeMethod is not a public instance method, you need to adapt the BindingFlags accordingly.

Upvotes: 0

Tejs
Tejs

Reputation: 41256

It sounds like you need a slight rethink of how you are doing things; if you have some other class that needs to use this BaseClass, without knowing what type of derived class it contains until you call a method, that seems inefficient.

public abstract class BaseClass
{
     public abstract void InitializeAndDoOtherStuff();
}

public abstract class DerivedA
{
     public overload void InitializeAndDoOtherStuff()
     {
         // Initializes the control, pass whatever you need into this method, etc)
     }
}

In which case, your code looks like so:

BaseClass bc = someVariable;
bc.InitializeAndDoOtherStuff();

OR

This is a horrible idea from code management perspective, but you could do something like this:

 public class DerivedA : BaseClass, IControlA { }
 public class DerivedB : BaseClass, IControlB { }
 ...

And then your other class has overloads like so:

 public void SomeMethod(IControlA control) { }
 public void SomeMethod(IControlB control) { }
 ...

Then, in your code it would be as easy as:

BaseClass bc = someVariable;
SomeMethod(bc);

And overload resolution would take care of it because the appropriate interface is only on one derived class.

Upvotes: 0

Gustavo Maciel
Gustavo Maciel

Reputation: 652

public class BaseClass {
    public virtual void SomeMethod()
    {
    }
};

public class DerivedA : BaseClass {
    public override void someMethod()
    { //Do DerivedA things
    }
};
public class DerivedB : BaseClass {
    public override void someMethod()
    { //Do DerivedB things
    }
};
public class DerivedC : BaseClass {
    public override void someMethod()
    { //Do DerivedC things
    }
};

Then you can do:

BaseClass bc = new BaseClass();

or

BaseClass bc = new DerivedA();

or

BaseClass bc = new DerivedB();

or

BaseClass bc = new DerivedC();

and just call:

bc.SomeMethod();

Even the BC type being BaseClass, if you instantiate as a derived, the derived method will be called. That means Inheritance and polymorphism.

this code is equilavent to yours.

Even yours, you can be better using typeof(); ;)

Upvotes: 1

Frederik Gheysels
Frederik Gheysels

Reputation: 56974

Isn't it appropriate to make SomeMethod a member method of your class ?

If DerivedA, DerivedB, etc... all share the same parent, then you can create this method as a virtual member method in the parent-class, and override it in the classes that inherit from it. (This is not specific to .NET 3.5 -or any other .NET version whatsoever-, this is just one of the basic OOP features)

Like this:

public class BaseClass
{
   public virtual void SomeMethod()
   {
       Console.WriteLine ("BaseClass");
   }
}

public class DerivedA : BaseClass
{
    public override SomeMethod()
    {
        Console.WriteLine("DerivedA");
    }
}

public class DerivedB : BaseClass
{
    public override SomeMethod()
    {
       Console.WriteLine ("DerivedB");
    }
}

BaseClass bc = someVariable;

bc.SomeMethod();

Upvotes: 4

Related Questions