Затенение событий в .NET

В VB.NET есть ключевое слово «тени». Допустим, у меня есть базовый класс под названием «Джедай» и производный класс под названием «Йода», который наследуется от «Джедай». Если я объявлю метод в «Джедае» под названием «ForcePush» и скрою его в «Йода», то при вызове метода для экземпляра класса «Йода» он будет игнорировать реализацию базового класса и использовать реализацию производного класса. . Однако, если у меня есть экземпляр «Йода», который изначально был объявлен как тип «Джедай», то есть Dim j as Jedi = new Yoda(), и вызывал метод «ForcePush» для экземпляра, он будет использовать реализацию джедая.

Теперь предположим, что у меня есть событие под названием «UsingForce», которое вызывается при вызове метода «ForcePush», и я затеняю событие в производном классе (это потому, что «Yoda» имеет интерфейс «IForcePowers», который объявляет это событие), и каждый класс вызывает соответствующее событие.

Если у меня есть экземпляр «Йода», объявленный как тип «Джедай» (как указано выше), и я добавляю обработчик события «Использование силы» для «Джедай», а затем метод «ForcePush» вызывается в « Йода, будет ли достигнут этот обработчик событий?


person dnatoli    schedule 08.09.2009    source источник
comment
Это потрясающий вопрос. Я собираюсь использовать пример джедая/Йоды в следующий раз, когда мне придется объяснять наследование.   -  person David    schedule 08.09.2009
comment
Дэвид: Я согласен, это потрясающе, настолько потрясающе, что отвлекло меня от самого вопроса, и в итоге я какое-то время просто думал о звездных войнах.   -  person Noon Silk    schedule 08.09.2009
comment
Извините, ребята, в следующий раз я постараюсь сделать свои вопросы немного менее крутыми! :)   -  person dnatoli    schedule 08.09.2009


Ответы (1)


Использование ключевого слова shadows в VB.NET означает, что вы объявляете совершенно новый элемент, существующий вне любой существующей иерархии наследования. Вот почему это ключевое слово (и связанная с ним практика) обычно считается «вонючим» (хотя некоторые люди возражают против этого конкретного термина, я считаю его вполне уместным). Какова причина этого шаблона «затенения вещей»? Этот подход обычно зарезервирован для обстоятельств, когда нет другого способа добиться того, что вам нужно. Было ли наследование и переопределение методов не вариантом?

В любом случае, если вы «затеняете» событие в более низком классе, то нет, у класса, находящегося выше по цепочке наследования, нет возможности напрямую инициировать событие, поскольку они понятия не имеют, что оно вообще существует.

person Adam Robinson    schedule 08.09.2009
comment
Вы не можете переопределить события, и причина, по которой мне нужно реализовать это в производном классе, заключается в том, что производный класс использует интерфейс, который предоставляет событие, поэтому, когда я объявляю объект типа «IForcePowers» с событиями, я могу добавить статический обработчик объекта. - person dnatoli; 08.09.2009
comment
Если интерфейс объявляет какой-либо член — будь то функция, свойство или событие — и член с совпадающим именем и сигнатурой уже реализован либо в реализующем классе, либо в одном из его базовых классов, то этот член будет автоматически учитываться. к реализации интерфейса. IE, если бы мне нужно было объявить интерфейс с именем IText со свойством Text, типизированным как строка, то я мог бы наследоваться от любого элемента управления и объявить, что он реализует интерфейс IText без какого-либо дополнительного кода, поскольку свойство Text строки уже существует. - person Adam Robinson; 08.09.2009
comment
@AdamRobinson: Нет. Вы должны явно указать свойство, отображающее строку, которое должно реализовывать рассматриваемый интерфейс/член, с ключевым словом Implements (в данном случае за ним следует IText.Text). В этом проблема, и проблема специфична для событий (поскольку они не могут быть объявлены Overridable), поэтому использование методов или свойств в качестве примеров вводит в заблуждение. - person d7samurai; 12.02.2013