2012-05-17 3 views
2

Допустим, у меня есть это:Какой метод вызывается, если я вызываю унаследованную перегрузку?

class A { } 
class B : A { } 
class C : B { } 

class Foo 
{ 
    public void Bar(A target) { /* Some code. */ } 
} 

class AdvancedFoo : Foo 
{ 
    public void Bar(B target) 
    { 
     base.Bar(target); 
     // Some code. 
    } 
} 

sealed class SuperiorFoo : AdvancedFoo 
{ 
    public void Bar(C target) 
    { 
     base.Bar(target); 
     // Some code. 
    } 
} 

Какая перегрузка будет вызываться, если я бегу new SuperiorFoo().Bar(new C()) и почему? Я предполагаю, что это будет называться cascadely, но я не могу понять, почему и если это поведение гарантировано.

ОБНОВЛЕНО

Таким образом, base. работает как с Foo и AdvancedFoo для SuperiorFoo, так какой из них будет называться и почему?

+1

Бар не является статическим, поэтому вы не можете назвать SuperiorFoo.Bar –

+0

Поскольку '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' – dasblinkenlight

+0

@SachinKainth, как вы можете видеть, это «новый SuperiorFoo.Bar (..)». @ dasblinkenlight нет, они не будут. Они принимают разные типизированные аргументы, так что это перегрузка. – AgentFire

ответ

6

Отредактировал свой ответ, теперь, когда вопрос был пересмотрен.

Быстрый след показывает следующее:

Entering SuperiorFoo.Bar() 
Entering AdvancedFoo.Bar() 
Entering Foo.Bar() 
Leaving Foo.Bar() 
Leaving AdvancedFoo.Bar() 
Leaving SuperiorFoo.Bar() 

Давайте говорить через то, что происходит:

  1. SuperiorFoo.Bar() вызывает базовый метод. Поскольку SF.Bar() наследует от AdvancedFoo, его базовым методом является AdvancedFoo.Bar().

  2. AdvancedFoo.Bar() затем вызывает свою базу, которая является Foo.Bar() с AdvancedFoo наследует от Foo().

Поток процесса НЕ перескакивает из SF.Bar() в Foo.Bar(), потому что вы можете потенциально хотеть поведение промежуточного класса.

Если мы удалим метод из AdvancedFoo, обход немного отличается. SuperFoo.Bar() по-прежнему вызывает свой базовый метод, но поскольку AdvancedFoo больше не скрывает метод Foo.Bar(), логика переходит к методу Foo.Bar().

+0

Черт .. я опаздываю на вечеринку +1 – V4Vendetta

+1

«Stackoverflow» on So –

+0

Извините, я забыл добавить «базу». для звонков. Исправлена. – AgentFire

0

Это будет вызов метода Bar() в функции SuperiorFoo до тех пор, пока он не завершится с помощью исключения StackOverflowException. Если вы хотите, чтобы вызвать базовый метод Bar() (так что метод внутри AdvancedFoo), вы должны будете использовать это:

base.Bar(target); 

Edit:

Похоже код в исходное сообщение было изменилось. Что происходит сейчас, так это то, что «Bar» в SuperiorFoo будет называть «Bar» AdvancedFoo, который вызовет «Bar» Foo, и после этого код будет прерван.

+0

Да, это то, что я сделал. – AgentFire

+0

Вы изменили свой код, не так ли? ;) Я вложил его в VS10, но в моем коде нет «базы». –

+0

Да, я это изменил. – AgentFire

0

Хотя KingCronus в основном указал, что у вас бесконечный цикл. Подпись попытается первый матч на основе точного типа объекта к соответствующему методу, то должен идти вниз от ...

class Foo 
{ 
    public void Bar(A target) { /* Some code. */ } 
} 

class AdvancedFoo : Foo 
{ 
    public void Bar(B target) 
    { 
     base.Bar((A)target); 
     // continue with any other "B" based stuff 
    } 
} 

sealed class SuperiorFoo : AdvancedFoo 
{ 
    public void Bar(C target) 
    { 
     base.Bar((B)target); 
     // continue with any other "C" based stuff 
    } 
} 

По типажей в «Другой» типа (т.е. B или A) , он поднимется до соответствующей цепи ...

+0

Бесконечный цикл был вызван ошибкой со стороны OP при копировании/вставке. С тех пор я изменил свой ответ :-) – KingCronus

 Смежные вопросы

  • Нет связанных вопросов^_^