SomeMethod
должен быть объявлен как виртуальный в A, чтобы успешно переопределить его в B.
public virtual int SomeMethod() // in A
public override int SomeMethod() // in B
С этим правильно на месте
A a = new B();
int value = a.SomeMethod();
Debug.Assert(value == 3); // succeeds
Если у вас вместо есть
public int SomeMethod() // in A
public new int SomeMethod() // in B, or just
public int SomeMethod() // in B
Тогда приведенное выше утверждение не выполняется.Метод в B скрывает базовый метод, но только через ссылку B.Работая по ссылке A, вы получаете базовое поведение.
A a = new B();
int value = a.SomeMethod(); // gets 1 from A, not 3 from B
ОБНОВЛЕНИЕ: Класс A уже написан и для всех целей и задач не может быть отредактирован.Я могу управлять только классом B. Зная, что класс B будет приведен к типу A, я просто хочу, чтобы моя реализация использовалась, когда SomeMethod () вызывается для моего tytypeasted B.
Методы не являются виртуальнымипо умолчанию в C #.Если авторы A
не разработали его с учетом расширяемости (по крайней мере, до переопределения SomeMethod
), вы не сможете заменить или переопределить это поведение на B
, когда оно рассматривается как A
.Однако, , если вы в состоянии контролировать приведение , или, скорее, зависимость кода, вы, возможно, можете инвертировать его так, чтобы A
фактически придерживался контракта B
, а не наоборот.Рассмотрим, например, шаблон адаптера .
interface IB
{
int SomeMethod();
}
class B : IB
{
public int SomeMethod() { return 3; }
}
class ABAdapter : IB
{
private A a;
public ABAdapter(A a) { this.a = a; }
public int SomeMethod() { return a.SomeMethod(); }
}
В этом примере вы использовали адаптер для шаблона, чтобы A
фактически выполнял контракт B
через интерфейс IB
.Таким образом, код, который когда-то мог зависеть от A
или B
, теперь может зависеть от IB
.ABAdapter просто делегирует реализацию A.
public void DoSomething(IB ib) // given
A a = new A();
DoSomething(new ABAdapter(a)); // invoke with A
DoSomething(new B()); // invoke with B