0

以下代码显示了使用ref关键字的引用传递示例。

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; }
}

如果没有ref关键字,它将按值传递,我得到的输出将是 10 和 15。

但是,使用ref关键字,我实际上得到了 5 和 15 的输出!为什么没有 ref 的代码指向 in 的方法,classA而有 ref 的代码指向 in 的方法classB?我猜它必须与多态性有关 -classB继承class A,但你如何解释它?

4

3 回答 3

2

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.

于 2013-04-27T21:50:31.760 回答
2

为什么没有 ref 的代码指向 classA 中的方法,而有 ref 的代码指向 classB 中的方法?

您的代码调用ClassB.MethodAClassA.MethodB. 总是。没有处理ref...

于 2013-04-27T21:27:11.303 回答
2

这不是要不要的问题ref

您有ClassA a = new ClassB();,即a具有编译时类型ClassA,但运行时类型更为派生,即ClassB.

1:你调用virtual方法MethodA。此方法覆盖ClassB,因此由于虚拟调度,使用了覆盖的实现。

2:你调用virtual方法MethodB。此方法(继承但)未被覆盖。因此,使用了它的“原始”(也是唯一的)实现ClassA。正如我所说,ClassA是 的编译时类型。引入具有相同名称和签名的新方法a的事实ClassB无关紧要。也许您错误地省略了关键字?编译器给你一个关于隐藏方法的警告。override

始终避免引入隐藏从基类继承的现有成员的新成员(在派生类中)。相反,尝试使用与现有成员不冲突的新名称(标识符)或新签名。或者可能根本不派生自基类。

于 2013-04-27T22:09:00.337 回答