質問

出力:
B->こんにちは!から顕在化する。

ながれ:?
A->こんにちは!から顕在化する。

が記載されていないのはなぜ明示的にキャスト(IHello)の呼び出IHello.こんにちは()からクラス。

interface IHello
{
    void Hello();
}

class A : IHello
{

    public virtual void Hello()
    {
        Console.WriteLine("A->Hello!");
    }

    void IHello.Hello()
    {
        Console.WriteLine("A->Hello! from Explicit.");
    }
}

class B : A, IHello
{
    public override void Hello()
    {
        Console.WriteLine("B->Hello!");
    }

    void IHello.Hello()
    {
        Console.WriteLine("B->Hello! from Explicit.");
    }
}

class Program
{
    static void Main(string[] args)
    {
        A a = new B();
        ((IHello)a).Hello();
    }
}
役に立ちましたか?

解決

いいえ、いよいと思います。

を呼び出 Hello 同氏-ひとつのルートを IHello なのないかぎり、実行する必要があの時の確認または変換);のコンパイル時の型は IHello もしかしたら、インターフェースのマッピングは同じとします。

がインターフェースは明示的に実施回以上の階層型の実装に由来タイプを使用します。(そういうわけで、これをインターフェース。)

から部13.4.4のC#3.0仕様:

タマッピングのためのクラスまたは struct C置を実施 各メンバーの各インタフェース 指定された基底クラスのリストCの実装に特定の インタ員I.M,Iを インタフェースの会員はM 宣言された定めによる検討 各クラスまたはstruct S開始 Cを繰り返し毎に歴代の の基底クラスCまでの間、試合は ホ:

  • そうでない場合、Sが含まれて宣言 の明示的なインタ員 実施に合っとM そしてこの委員は、実装 の研究
  • そうではない場合、Sが含まれて宣言への非公開の会員と一致するM、そしてこの委員は、実施の研究場合により試合では指定される委員は、実施の研究この状況をできるだけた場合に生じる"S"は構築型を会員として宣言した汎用タイプの異なる署名の型引数を署名と同一です。

他のヒント

(A)Aは何もしません。参照がまだAにキャストすることは効果がありませんように宣言されます。

あなたはIHelloにこのオブジェクトをキャストする場合は、

あなたの参照は、Aとして宣言されていても、それが参照するオブジェクトは、タイプBのものであり、こんにちは()の呼び出しでは、ハローのオブジェクトBの明示的な実装を呼び出します。

出力が期待どおりにある。

あなたが新しいの方法(ToStringメソッド)を作成するとき、

いいえ、それは仮想ではありません。新はちょうどあなたが、基本クラスでバージョンを「隠し」、それを気にしないことを意味します - ので、あなたは、特定のタイプ(A)にキャストしていることを参照して、それを呼び出す場合、それは関係なく、クラスAにメソッドを実行しますあなたが呼び出しているオブジェクトの実際の型。 (すなわちあなたがA.ToString(と呼ばれる)ので、それはA.ToStringを実行する())

するときは、その後の仮想の方法、あなたが呼ばれたときにタイプに関係なく何のあなたがへの参照をキャストし、オブジェクトの実際の型からの実装が使用されている(つまり、あなたがそう、Bを作成を作成します.Hello(対象が何であれ)、それが呼ばれるB.Hello)

決定的な違いは、1つのコールが仮想であり、他はないということです。

いいえ、それはいけない。

あなたは仮想メソッドを呼び出している場合は、

、参照の型が何であるかは重要ではありません。呼び出されるメソッドは、オブジェクトの実際の型ではなく、参照のタイプによって決定されます。

あなたはクラスBのインスタンスを作成すると、

、オブジェクトの実際の型はBです。それは"This is class A."を印刷した理由は、あなたがクラスToStringBメソッドをオーバーライドしていないということです、あなたはnewキーワードを使用して、それを影にしています。従ってBクラスは、二つToStringメソッド、クラスA及びそれをシャドウ一方から継承つを有します。あなたはAメソッドを呼び出すためにToStringリファレンスを使用する場合は、継承されたメソッドが呼び出されますが、あなたはそれを呼び出すためにB参照を使用していたならば、シャドウイング方式は"This is class B."をプリントアウトし、呼び出されます。

また、あなたが代わりにそれをシャドウイングのクラスToStringBメソッドをオーバーライドした場合、それは参照の種類に関係なく"This is class B."をプリントアウトします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top