I'm not even sure what it's called or even if it's possible, what I'm trying to do.
I'm hoping the code might explain it.
Each class that derives from Base has a method named oPrint, and I want to call them in the below fashion(ish) if possible.

namespace nSpace
{
    class Base
    {
        public void Print(object val)
        {
            Console.WriteLine("Printing a " + val.GetType());
        }
    }

    class Class1 : Base
    {
        public string val = "1";
        public void oPrint()
        {
            Print(val);
        }
    }

    class Class2 : Base
    {
        public int val = 1;
        public void oPrint()
        {
            Print(val);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Base[] reg = new Base[2];
            reg[0] = new Class1();
            reg[1] = new Class2();

            foreach (Base r in reg)
            {
                r.oPrint(); // Base does not contain a definition for oPrint
            }
            Console.ReadKey();
        }
    }
}

Any help with my failings is appreciated.

Recommended Answers

All 12 Replies

virtual and override is what you are looking for:

namespace nSpace
{
    class Base
    {
        public virtual void Print(object val)
        {
            Console.WriteLine("Printing a " + val.GetType());
        }
    }
    class Class1 : Base
    {
        public string val = "1";
        public override void Print()
        {
            Print(val);
        }
    }
    class Class2 : Base
    {
        public int val = 1;
        public override void Print()
        {
            Print(val);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Base[] reg = new Base[2];
            reg[0] = new Class1();
            reg[1] = new Class2();
            foreach (Base r in reg)
            {
                r.Print();
            }
            Console.ReadKey();
        }
    }
}

Override methods on MSDN

commented: Beat me to it, this is exactly what you want +7

Thanks for suggestion guys.
there is a problem with that though.

    class Class2 : Base
    {
        public int val = 1;
        public override void Print() //no suitable method found to override
        {
            Print(val);
        }
    }

I imagine because the method in base class takes parameter.

commented: Right. Didn't notice. +14

Thought this might be a sneaky workaround, but for some reason causes a stack overflow exception when it runs.

namespace nSpace
{
    class Base
    {
        public virtual void Print(object val)
        {
            Console.WriteLine("Printing a " + val.GetType());
        }
    }

    class Class1 : Base
    {
        public string val = "1";
        public override void Print(object o)
        {
            Print(val);
        }
    }

    class Class2 : Base
    {
        public int val = 1;
        public override void Print(object o)
        {
            Print(val);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Base[] reg = new Base[2];
            reg[0] = new Class1();
            reg[1] = new Class2();

            foreach (Base r in reg)
            {
                r.Print(1);
            }
            Console.ReadKey();
        }
    }
}

OK, I got workaround to function properly, by prepending base keyword to Print call...

    class Class1 : Base
    {
        public string val = "1";
        public override void Print(object o)
        {
            base.Print(val);
        }
    }

still feel I'm doing something hacky though.

Nah you did it correctly. The reason you got a stack overflow, you were calling print in your Class1, which was calling itself.

Usually you use a virtual/override when you want the base class to function a certain way, but you can override the logic (there is also the abililty to do tricks that Interfacing allows for, in relation to calling a function or what not). However, I do feel that while your example does show a good way to use inheritance, it might be a little over the top for what you need. In your case I think something like this might have worked easier

namespace nSpace
{
    class Base
    {
        protected object val = new object();

        public void Print()
        {
            Console.WriteLine("Printing a " + val.GetType());
        }
    }
    class Class1 : Base
    {
        val = "1";
    }
    class Class2 : Base
    {
        val = 1;
    }
    class Program
    {
        static void Main(string[] args)
        {
            Base[] reg = new Base[2];
            reg[0] = new Class1();
            reg[1] = new Class2();
            foreach (Base r in reg)
            {
                r.Print();
            }
            Console.ReadKey();
        }
    }
}

Here you let the base "Print" do its thing like always, but instead, by using object, you can actually change the type. Now in this example it works vert nicely without any virtual or override because it's a type object.

I can go on about how you can actually use virtual/override in relation to say a custom object, and have the Base class contain a base Item, that an inheriting Base class, can use an inherited Item (that item inheriting the custom object). But I'll let you soke this in first, as this I can explain easier with code (I probably already confused you)

Oh yeah I used protected so no class could touch the "val" variable outside of those that inherit the Base

(Sorry for all the rambling I've been experimenting a lot with inheritance lately and have learned some very cool tricks you can do with it)

commented: Knowledge! +15

That's great, much better I think for what I need.
This project I'm working on is teaching me a lot. While it's been fine and functioning for some time, I keep seeing different and better ways to implement it.

Either way above will probably shave 1/4 off my current code lines, which I have already halved in the past week, and save me a lot of typing and time in the future.

Thank you again, for your time and knowledge.

Unfortunately, I cannot understand how to access the base field "val" from Class1.

    class Class1 : Base
    {
         val = "1"; // the name var does not exist in this context
    }

    class Class2 : Base
    {
         base.val = 1; // same
    }

Also 'base' and '=' are invalid tokens.

Never mind, derived classes needed a constructor.

Regarding the Base class, is there any benefit to having the val object declared as new?
protected object val = new object();

as opposed to

protected object val = null;

is there any benefit to having the val object declared as new

That only assures that val will always be instantiated with an object instance. Personally I prefer null so you know it hasn't been assigned yet or the assigment has been removed at some point. I assume the reason is because of the GetType(). Adding a null check would be my preference.

commented: Good point, null checks are always good to have +0

I used the initialization to prevent it from blowing an exception. If you try to pull a GetType for a null, it throws an exception. Pritaeas makes a good point, it might be wise to put a null checker, since even if you don't initally set it to null, the user could with a derived class.

Once you start to learn inheritance more, you quickly start looking a little different on how you design things. I really got into it with a custom SQLite library I am developing, but also, some windows form component I have developed which use a lot of repetative code (I actually can't believe I didn't learn it sooner ... now just to find the correct use for interfaces)

Thanks all, much appreciated.
Enjoying a lovely oop learning burst.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.