Как это будет работать? (интерфейсы и не виртуальные функции) - PullRequest
2 голосов
/ 05 мая 2009
interface I { int J(); }

class A : I
{
   public  int J(){return 0; }  // note NOT virtual (and I can't change this)
}

class B : A, I
{
   new public int J(){return 1; }
}


B b = new B();
A a = b;
I ib = b, ia = a;

b.J(); // should give 1
a.J(); // should give 0 (IMHO)

ia.J(); // ???
ib.J(); // ???

Я знаю, что я мог бы просто попробовать это, но я ищу хороший авторитетный источник для всего этого угла, и я бы предпочел не просто начать копаться в текстах MSDN (у меня нет угадайте, для чего Google).

Ответы [ 3 ]

2 голосов
/ 05 мая 2009

Переписано: Поскольку мы говорим о реализации IDisposable, то, что действительно имеет значение, так это то, что классы Derived и Base имеют возможность запускать свой соответствующий код очистки. Этот пример будет охватывать 2/3 сценария; однако, поскольку он является производным от Base () и Base.Dispose () не является виртуальным, вызовы, сделанные для ((Base) Child) .Dispose () не предоставят классу Child возможность очистки.

Единственный обходной путь - не выводить Ребенка из Базы; Однако это было исключено. Вызовы ((IDisposable) Child) .Dispose () и Child.Dispose () позволят и Child, и Base выполнить свой код очистки.

class Base : IDisposable
{
    public void Dispose()
    {
        // Base Dispose() logic
    }
}

class Child : Base, IDisposable
{
    // public here ensures that Child.Dispose() doesn't resolve to the public Base.Dispose()
    public new void Dispose()
    {
        try
        {
            // Child Dispose() logic
        }

        finally
        {
            // ensure that the Base.Dispose() is called
            base.Dispose();
        }
    }

    void IDisposable.Dispose()
    {
        // Redirect IDisposable.Dispose() to Child.Dispose()
        Dispose();
    }
}
1 голос
/ 01 июня 2011

Джеффри Рихтер (CLR через C #): «Компилятор C # требует, чтобы метод, реализующий интерфейс, был помечен как открытый. CLR требует, чтобы методы интерфейса были помечены как виртуальные. Если вы явно не пометите метод как виртуальный в вашем исходном коде, компилятор помечает метод как виртуальный и запечатаны; это предотвращает переопределение производного класса методом интерфейса. Если вы явно пометить метод как виртуальный, компилятор помечает метод как виртуальный (и оставляет его открытым); это позволяет производному классу переопределить метод интерфейса "

1 голос
/ 05 мая 2009

Неважно, что вы говорите с контрактом, предоставленным базовым классом или интерфейсом, они все вернут 1, потому что вы говорите с экземпляром класса B.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...