2

C++では「使用」で行われ、C#では?

public class foo
{
   public void print(string s) {...}
}

public class bar : foo
{
   // shadowing
   public void print(object o) {...}
}

を昇格させる方法foo.print、したがってfoo.printbar.printコンパイラーと同じ「レベル」になります(barもちろん)?

更新 1

最初に、シャドウイングとオーバーライドの一般的な混同に関する段落を追加しましたが、読者に不快感を与えると考えたため、削除しました。

シャドウイングは、継承ツリーにまたがるオーバーロードのようなものです。シャドーイングはオーバーライド されません。

更新 2

オーバーロードされたメソッドを解決するときに、シャドーイングの後foo.printが考慮されなくなりましたprint。昇格するfoo.printと、プロセスに戻ります。つまり、メソッドを呼び出すとbar_object.print("hello")、メソッドfoo.printが呼び出されます。

4

1 に答える 1

3

あなたの具体的な例では、bar.print(object)確かに、より具体的な「影」がありますfoo.print(string)

new bar().print("i am a string");

これにより、で定義されたメソッドが呼び出されますbarが、のメソッドにfooは、タイプによりよく一致するパラメーターがあります。ここで何が起こるかは次のとおりです。コンパイラは、正しい名前( "print")、正しい数のパラメータ(1)、および渡されたパラメータを変換可能な(に変換できる)パラメータタイプを
持つメソッドを見つけます。。 このため、コンパイラが継承チェーンをさらに検索する理由はありません。barstringobject

私の知る限り、C++に似た構造はありませんusing
基本クラスで定義されたメソッドを使用する場合、基本的に3つのオプションがあります。

  1. 呼び出し側:barインスタンスを次のように変換しますfoo

    var bar = new bar();
    var foo = (foo)bar;
    foo.print("i am a string"); // Will call foo.print(string)
    
  2. calee側:内部bar.print(object)で渡されたパラメーターのタイプを確認します。

    public void print(object o)
    {
        var s = o as string;
    
        if(s != null)
            base.print(s);
        else
        {
            // Other code.
        }
    }
    
  3. これはC++に最も近くなりusingます:派生クラスの元のメソッドを実際にオーバーライドまたは非表示にします:

    public class bar : foo
    {
        public new void print(string s)
        {
            base.print(s);
        }
    
        public void print(object o)
        {
            // some code
        }
    }
    
于 2012-12-10T12:36:41.880 に答える