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 のないコードは のメソッドをclassA指しているのに、ref のあるコードは のメソッドを指しているのはclassBなぜですか? classBポリモーフィズム - inheritsで何かをしなければならないと推測してclass Aいますが、どのように説明しますか?

4

3 に答える 3

2

ref のないコードは classA のメソッドを指しているのに、ref のあるコードは classB のメソッドを指しているのはなぜですか?

あなたのコードはClassB.MethodAand を呼び出しますClassA.MethodB。いつも。との取引はありませんref...

于 2013-04-27T21:27:11.303 に答える
2

これは、refかどうかの問題ではありません。

ClassA a = new ClassB();つまり、aコンパイル時の型がありますClassAが、実行時の型はより派生したもの、つまりClassBです。

virtual1:メソッドを呼び出しますMethodA。このメソッドによってオーバーライドされるClassBため、仮想ディスパッチのために、オーバーライドされた実装が使用されます。

2:virtualメソッドを呼び出しますMethodB。このメソッドは (継承されますが)オーバーライドされません。したがって、その「元の」(そして唯一の) 実装ClassAが使用されます。私が言ったようにClassA、 のコンパイル時の型です。同じ名前と署名を持つ新しいメソッドを導入するaという事実は関係ありません。間違ってキーワードを省略した可能性がありますか?コンパイラは、メソッドを非表示にすることについて警告を出しました。ClassBoverride

基本クラスから継承された既存のメンバーを隠す新しいメンバーを (派生クラスで) 導入することは常に避けてください。代わりに、既存のメンバーと競合しない新しい名前 (識別子) または新しい署名を使用してみてください。または、基本クラスからまったく派生しないかもしれません。

于 2013-04-27T22:09:00.337 に答える
2

ClassB.MethodB は ClassA.MethodB をオーバーライドせず、ClassA 参照から MethodB を呼び出しています。

その場合に ClassB.MethodB を呼び出したい場合は、override キーワードを追加する必要があります。そうでない場合は、.net がそれを別のメソッドとして識別します。

于 2013-04-27T21:50:31.760 に答える