【问题标题】:Pass by value vs Pass by reference with polymorphism通过值传递与多态性通过引用传递
【发布时间】:2013-04-21 20:03:38
【问题描述】:

以下代码显示了使用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的代码指向classA中的方法,而带ref的代码指向classB中的方法?我猜它与多态性有关——classB 继承了class A,但你如何解释呢?

【问题讨论】:

  • 阅读编译器警告;他们正在告诉你这里发生了什么。

标签: c# polymorphism pass-by-reference pass-by-value


【解决方案1】:

ClassB.MethodB 不会覆盖 ClassA.MethodB,并且您是从 ClassA 引用调用 MethodB。

如果您希望在这种情况下调用 ClassB.MethodB,则必须添加 override 关键字,如果不是 .net 将其标识为另一种方法。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      这不是ref与否的问题。

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-14
        • 1970-01-01
        • 2020-04-01
        • 2020-12-06
        • 2011-08-21
        • 1970-01-01
        • 1970-01-01
        • 2013-06-27
        相关资源
        最近更新 更多