BOOnZ
BOOnZ

Reputation: 848

Pass by value vs Pass by reference with polymorphism

The following code shows a pass by reference example using ref keyword.

class Program
{
    static void Main(string[] args)
    {
        int c1 = 10;
        ClassC c2 = new ClassC(10);
        ClassA a = new ClassB();

        a.MethodA(ref c1); Console.WriteLine(c1);
        a.MethodB(ref c2); Console.WriteLine(c2.getC());

        Console.Read();
    }
}

class ClassA //base class
{
    public virtual void MethodA(ref int c1)
    {
        c1 = c1 + 5;
    }
    public virtual void MethodB(ref ClassC c2)
    {
        c2.setC(c2.getC() + 5);
    }
}

class ClassB : ClassA  //ssubclass
{
    public override void MethodA(ref int c1)
    {
        c1 = c1 - 5;
    }
    public void MethodB(ref ClassC c2)
    {
        c2.setC(c2.getC() - 5);
    }
}


class ClassC //just a class with a variable c with get/set methods
{
    protected int c;
    public ClassC(int CValue) { c = CValue; }
    public void setC(int cnew) { this.c = cnew; }
    public int getC() { return c; }
}

If there is no ref keyword, it would be pass by value and the output I get would be 10 and 15.

However, with the ref keyword, I actually get an output of 5 and 15! Why does the code without ref point to the method in classA while the code with ref points to the method in classB? I'm guessing it has got to do something with polymorphism - classB inherits class A, but how do you explain it?

Upvotes: 0

Views: 347

Answers (3)

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 61952

This is not a question of ref or not.

You have ClassA a = new ClassB();, that is a has compile-time type ClassA, but the run-time type is more derived, namely ClassB.

1: You call the virtual method MethodA. This method is overridden by the ClassB, so because of the virtual dispatch, the overridden implementation is used.

2: You call the virtual method MethodB. This method is (inherited but) not overridden. Therefore its "original" (and only) implementation in ClassA is used. ClassA is the compile-time type of a, as I said. The fact that ClassB intoduces a new method with the same name and signature is not relevant. Maybe your omitted the override keyword by mistake? The compiler gave you a warning about hiding a method.

Always avoid introducing a new member (in a derived class) which hides an existing member inherited from the base class. Instead, try to use a new name (identifyer), or a new signature, which does not conflict with the existing member. Or maybe don't derive from the base class at all.

Upvotes: 2

tukaef
tukaef

Reputation: 9214

Why does the code without ref point to the method in classA while the code with ref point to the method in classB?

Your code calls ClassB.MethodA and ClassA.MethodB. Always. There is no deal with ref...

Upvotes: 2

fbiagi
fbiagi

Reputation: 826

ClassB.MethodB does not overrides ClassA.MethodB, and you are calling MethodB from a ClassA reference.

if you want ClassB.MethodB to get called in that case, you'll have to add the override keyword, if not .net identify it as another method.

Upvotes: 2

Related Questions