1

I have an abstract base class called Rack and I have different types of racks that are the children of Rack. I want to be able to dynamically cast the generic C# object to different children of the Rack class in order to call the correct getData method in which all children have as a method. Here is what I have so far.
The code below calls the virtual method in the Rack base class. I need it to call the methods within the child classes of Rack.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace IO_Interface
{
class Channel
{
    private object rack1;
    private object rack2;
    public Channel()
    {

    }

    public Channel(object h1, object h2)
    {
        rack1 = h1;
        rack2 = h2;
    }

    public void send()
    {

        Type rack1Info = rack1.GetType();
        Type rack2Info = rack2.GetType();
        string name = rack1.ToString();

        MethodInfo castMethod = rack1.GetType().GetMethod("getData").;
        castMethod.Invoke(rack1.GetType(), null);

    }

}
}`
3
  • Why can't you just type rack1 and rack2 as Rack and call the getData method directly? Commented Aug 28, 2013 at 21:29
  • If it's virtual it will call it anyways. If it's new you have a problem. Commented Aug 28, 2013 at 21:30
  • Dynamic casting is not possible in a statically typed language like C#. It seems you just need a virtual method. Commented Aug 28, 2013 at 21:31

2 Answers 2

5

What you want to do is declare your rack1 and rack2 as Racks, which will be an abstract class with an abstract method GetData. You will instantiate them as child classes of Rack somewhere. Then, when you make a call to GetData on a Rack, it will find the overridden method and call it. Here's an example.

abstract class Rack
{
   public abstract void GetData();
}

class ChildRack1 : Rack
{
    public override void GetData(){}
}

class ChildRack2 : Rack
{
    public override void GetData(){}
}

class Channel
{
    private Rack rack1;
    private Rack rack2;
    public Channel()
    {

    }

    public Channel(Rack h1, Rack  h2)
    {
        rack1 = h1;
        rack2 = h2;
    }

    public void send()
    {

        rack1.GetData();
    }

}
Sign up to request clarification or add additional context in comments.

4 Comments

Rack doesn't need to be abstract - it can be a regular class. GetData just needs to be virtual if it has a base implementation and abstract if it doesn't.
Are you saying that when the send method is called the GetData will know to call the correct child method? When i set up the constructor I send it two children of Rack. I thought the constructor would cast down to the base and only call the virtual method but is there some property of the Rack object that still maintains its child type?
GetType will return the child type. However, if you properly mark things as abstract/virtual and override them, then C# will call the method that goes with the type it was instantiated with.
D Stanley is also correct I tested making the Rack class normal and making the methods virtual. I made sure each method used the overriden keyword and that does the job. Excellent!
0

I think this will provide you with the implementation you want:

    class Channel
    {
        private List<Rack> racks;

        public Channel()
        {
            racks = new List<Rack>();
        }

        public Channel(params Rack[] racks)
        {
            this.racks = racks.ToList();
        }

        public void send()
        {
            foreach (Rack item in racks)
            {
                item.getData();
            }

        }

        public void SendSpecificRack(Rack rack)
        {
            //calls the getdata of the rack object passed
            rack.getData();
        }

    }

    public class Rack
    {
        public virtual void getData()
        {
            Console.WriteLine("Base Rack");
        }
    }

    public class RackChild1 : Rack
    {
        public override void getData()
        {
            Console.WriteLine("RackChild1");
        }
    }

    public class RackChild2 : Rack
    {
        public override void getData()
        {
            Console.WriteLine("RackChild2");
        }
    }

Usage:

Channel chn = new Channel(new Rack[]{new RackChild1(),new RackChild2()});
chn.send();
RackChild2 rck = new RackChild2();
chn.SendSpecificRack(rck);

Output:

RackChild1
RackChild2
RackChild2

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.