Универсальный метод со строгой типизацией вызывает метод базового класса своего аргумента вместо теневого метода в T? - PullRequest
3 голосов
/ 20 октября 2010

Рассмотрим класс MyForm, который содержит теневую реализацию Show().Он также содержит метод CreateForm(), который принимает экземпляр формы и вызывает теневую подпрограмму:

Public Class MyForm
    Inherits Form

    Public Shadows Sub Show()
        MessageBox.Show("Shadowed implementation called!")
    End Sub
End Class

...

Public Sub CreateForm(ByVal childForm As MyForm)
    childForm.MdiParent = Me
    childForm.Show()
    childForm.Focus()
End Sub

При вызове с CreateForm(New MyForm()) корректно вызывается теневая реализация Show().Теперь рассмотрим следующую обобщенную реализацию:

Public Sub CreateForm(Of T As Form)(ByVal childForm As T)
    childForm.MdiParent = Me
    childForm.Show()
    childForm.Focus()
End Sub

При вызове CreateForm(Of MyForm)(New MyForm()) этот обобщенный метод со строгой типизацией никогда не вызывает затененный метод.

Это ошибка или я что-то упустил?

Ответы [ 3 ]

3 голосов
/ 20 октября 2010

Это поведение "По замыслу". Здесь нужно помнить, что универсальный метод компилируется и проверяется сам по себе (не в контексте вызывающей стороны, как это делается в C ++). Следовательно, универсальный метод знает только, что T относится к Form. Он не знает MyForm и поэтому правильно связывается с методами на Form.

Это правильно, потому что Shadows методы вступают в игру только с типом ссылки во время компиляции, что делает метод Shadow видимым. Это не тот случай, поскольку тип ссылки в типе компиляции равен Form (не MyForm). Это отличается от Overridable, где поведение изменяется в зависимости от типа среды выполнения.

2 голосов
/ 20 октября 2010

Вы что-то упускаете. Он только знает, что имеет дело с формой во время компиляции (помните, что дженерики не являются шаблонами!). Единственное, что вы можете сделать, - это использовать (переопределить) виртуальные методы вместо их теневого копирования.

См. Также «Тени» и «Переопределения» в VB.NET для получения дополнительной информации о теневом копировании - это на самом деле не полиморфизм.

1 голос
/ 20 октября 2010

Это не ошибка, потому что вызов оценивается компилятором статически только на основании заданных ограничений типа, примененных к T, то есть Form. Компилятор не может предсказать, что фактический тип может содержать объявление затененного метода или любой другой метод, не объявленный в известном родительском элементе (т.е. Form).

...