Наследование событий

Наследование событий С#

У меня есть эта программа:

Есть 2 класса — один и два, два — потомок одного. Событие объявляется в классе One (SomethingChanged), и оно запускается классом One и классом Two. Но взгляните на Two.ChangeSomething — он вызывает событие, вызвав метод базового класса. Однако, если я пытаюсь вызвать событие с использованием необработанного кода, например

Я получаю сообщение об ошибке компилятора

Так что мне просто любопытно, почему я не могу использовать «сырой» код в классе 2 для повышения события, но когда я вызываю соответствующее событие функции, возникает вопрос?

Когда вы объявляете событие с использованием ключевого слова «событие» в С#, сгенерированный IL фактически содержит два соответствующих элемента: поле частного делегата и средство доступа к событиям с той же видимостью, что и объявленное событие. Активатор события не может использоваться для запуска события. Он используется только для подписки и отмены подписки на уведомления. Ваш код SomethingChanged(this) использует приватное поле для вызова делегата, и это частное поле недоступно вне класса.

(кстати, имеет условие гонки) подразумевает вызов Delegate.GetInvocationList в SomethingChanged . Автоматически реализованные события не позволяют сделать это, если вы не находитесь в классе, в котором определено событие.

Вы могли бы сделать это, если бы вы внедрили событие вручную и предоставили protected доступ к полю делегата, поддерживающему событие.

Посмотрите другие вопросы по меткам c# events frameworks или Задайте вопрос

Зачем наследовать класс данных события от EventArgs

Зачем здесь в обработчике событий используются аргументы object sender, EventArgs e?
Здравствуйте! Подскажите пожалуйста , для чего в данной программе в строках 17, 26.

Возможно ли наследовать события
на форме две кнопки.при нажатии открываются формы для кнопок 1 и 2.Событие открытия ведь.

Создать унаследованный класс EventArgs
Необходимо создать класс MyEventArgs, унаследованный от EventArgs, с целью передачи обработчику.

Event Args, Класс данных события
Вот есть такие моменты, когда что-то не понимаешь и начинаешь кипеть как чайник. Я пересмотреть уже.

Как наследовать события
Здравствуйте! Создаю класс-наследник TImage. Не получается описать событие OnClick в конструкторе.

Решение

Все дело в ковариантности делегатов относительно параметров.

Если все события будут иметь сигнатуру вида void(object, EventArgs) , то это дает больше гибкости подписчикам по выбору методов-обработчиков, используемых для подписки на событие, то есть положительно влияет на ту же масштабируемость систем, упомянутую выше товарищем Bespridelschic.
Это так же позволяет подписываться на события уже во время выполнения, даже не зная тип, к событию которого производится подписка, как и саму сигнатуру делегата для обработки события. Полезно для реализации всякого рода плагинов.

Другими словами, если у вас есть метод, скажем void SomeEventHappened(object sender, EventArgs e) , то вы можете использовать этот метод для подписки на любое событие, например: void PropertyChanged(object, PropertyChangedEventArgs , void MouseMove(object, MouseEventArgs) , void FormClosing(object, FormClosingEventArgs) , MySuperEvent(MySuperClass, MySuperEventArgs) и так далее.

Имея на руках всего лишь один метод вы можете подписаться на любое событие любого класса (например, если вас не интересуют детали события, а нужен лишь факт регистрации его возникновения — в целях той же масштабируемости). Но для этого надо, чтобы все события имели какую-то общую структуру, отсюда и рекомендация: сигнатура события должна иметь возвращаемый тип void и два формальных параметра: объект, вызвавший событие и детали события в виде типа, наследующегося от EventArgs .

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

Переопределение события IndexOutOfRangeException используя наследование

Нужно переопределить событие при помощи наследования

Читайте так же:  Как оформить рабочий табель

Читаю задание и не совсем понимаю что от меня хотят -> следовательно не могу написать.

Может кто на примере показать на данном событии..как правильно его переопределить?

Реализовать обработку ошибок, при этом переопределив, используя наследование события StackOverflowException
Задание: Реализовать обработку ошибок, при этом переопределив с помощью наследования событие.

Наследование,переопределение методов[рефлексия]
Раньше я практически не сталкивался с рефлексией, но теперь появилась острая проблема .Загружаю.

Наследование и переопределение виртуальных методов
Здравствуйте уважаемые программисты. Помогите разобраться с наследованием и переопределением.

Переопределение virtual события
всем привет, имеется такой пример: public delegate void EventDelegate(); interface.

Наследование класса и переопределение переменных в наследуемых классах
Всем добрый день. Есть два класса, Класс А и класс Б который наследуется от класса А. В классе.

2) Построить иерархию классов в соответствии с вариантом задания(добавление редактирование, удаление и просмотр):
4. Деталь, механизм, изделие, узел

3) Расширить иерархию классов из задания №2 с использованием виртуального класса в качестве основы иерархии. Показать пример использования полиморфизма методов.

4) Реализовать для иерархии из задания №3 механизм интерфейсов, при этом один из классов должен реализовывать как минимум 2 интерфейса. Использовать для проверки всех методов данного класса многоадресный делегат.

5) Реализовать обработку ошибок задания №4, при этом переопределив с помощью наследования событие:
• StackOverflowException
• ArrayTypeMismatchException
• DivideByZeroException
• IndexOutOfRangeException
• InvalidCastException
• OutOfMemoryException
• OverflowException

Форум

Справочник

Опции темы Искать в теме

Вопрос родился по итогам стати Введение в события. Замечательная статья. Но задавшись элементарным вопросом, так и не смог реализовать его решение.

Смысл в следующем, создаем несколько вложенных слоев. (Как в примерах статьи) И на первый из них вешаем событие:

Насколько я понял из стати div c

Но вот как как ОСТАНОВИТЬ срабатывание события на «дочерних» к первому элементах, оставив по прежднему срабатывание алерта при событии на первом слое (с ) на всей поверхности слоя, в т.ч. и перекрытой слоями d2 и d3.

Следующий JS код отменит срабатывание события для слоя d2 (и как следовательно для d3):

Но и для области слоя d1 перекрытому слоем d2 тоже отменит.

Обьясняя проще в IE с версии 5.5 была введена функция onmouseenter и она срабатывает именно так как мне и требуется. Но исползовать ее глупо. Т.к. решение не кроссбраузерное.

Очень надеюсь на помощь профессионалов. Если не примером кода то хотя бы тычком носом в статью или еще какой мануал. Где было бы разжевано как реализовать выше изложенное.

Наследование generic-класса от интерфейса

У меня есть классы и интерфейсы:

Теперь мне нужен такой класс:

Естественно, компилятор требует реализации RangeObservableCollection.Items

Я бы мог сделать так:

Но у меня есть еще один класс:

А дальше уже конкретные UserControl’ы наследуются от UserControlBase. Для чего это мне? В UserControl’ах куча повторяющегося кода (в основном привязки событий ViewModel). Поэтому это все я хочу сделать в UserControlBase. Я бы мог объявить в UserControlBase так:

но тогда мне T нужно поднимать в UserControlBase, а это как-то криво.

Как мне наследовать EntityListViewModel от обычного IEntityListViewModel? Или есть какое-то другое решение?

UPD 1: Явно реализовал, как посоветовали в комментариях:

Но теперь во View вызов VM.Items обращается к IEntityListViewModel.Items

1 ответ 1

В текущем виде самым простым для вас было бы действительно объявить UserControlBase обобщенным. Если же этот способ вам по какой-то причине не подойдет — надо выносить хранение из базового класса в наследники.

В вашем случае, если базовый класс подписывается на события — ему нужен интерфейс INotifyCollectionChanged . Его и надо запрашивать у наследника:

Если при таком подходе в базовом классе оказывается слишком много полей — надо выделять в интерфейсе ковариантную часть.

Например, для ваш интерфейс IEntityListViewModel можно разбить следующим образом:

Реализовать такой «усложненный» интерфейс не сильно сложнее чем обычный:

После этого, ковариантную часть можно «пробросить» в базовый класс через абстрактное свойство:

Практическое руководство. Наследование форм Windows Forms How to: Inherit Windows Forms

Создание новых форм Windows Forms путем наследования базовых форм является удобным способом для дублирования уже созданного, минуя процесс повторного создания формы с нуля каждый раз, когда она необходима. Creating new Windows Forms by inheriting from base forms is a handy way to duplicate your best efforts without going through the process of entirely recreating a form every time you require it.

Читайте так же:  Региональная социальная доплата к пенсии неработающим пенсионерам

Дополнительные сведения о наследовании форм во время разработки с помощью диалогового окна «Выбор наследования » и о том, как визуально различать уровни безопасности наследуемых элементов управления, см. в разделе как Наследовать формы с помощью диалогового окнаВыбор наследования. For more information about inheriting forms at design time using the Inheritance Picker dialog box and how to visually distinguish between security levels of inherited controls, see How to: Inherit Forms Using the Inheritance Picker Dialog Box.

Для наследования из формы файл или пространство имен, содержащие эту форму, должны быть встроены в исполняемый файл или библиотеку DLL. In order to inherit from a form, the file or namespace containing that form must have been built into an executable file or DLL. Для сборки проекта выберите в меню Сборка пункт Собрать. To build the project, choose Build from the Build menu. Кроме того необходимо добавить ссылку на пространство имен к классу, наследующему форму. Also, a reference to the namespace must be added to the class inheriting the form.

Наследовать форму программным способом Inherit a form programmatically

В классе добавьте ссылку на пространство имен, содержащее форму, которую вы хотите наследовать. In your class, add a reference to the namespace containing the form you wish to inherit from.

В определении класса добавьте ссылку на форму для наследования. In the class definition, add a reference to the form to inherit from. Ссылка должна содержать пространство имен, в котором содержится форма, точку, а затем имя базовой формы. The reference should include the namespace that contains the form, followed by a period, then the name of the base form itself.

При наследовании форм следует помнить, что могут возникнуть проблемы с обработчиками событий, которые вызываются дважды, так как каждое событие обрабатывается базовым классом и производным классом. When inheriting forms, keep in mind that issues may arise with regard to event handlers being called twice, because each event is being handled by both the base class and the inherited class. Дополнительные сведения о том, как избежать этой проблемы, см. в разделе Устранение неполадок, связанных с унаследованными обработчиками событий в Visual Basic. For more information on how to avoid this problem, see Troubleshooting Inherited Event Handlers in Visual Basic.

Применение наследования при генерации WEB-страниц на чистом JavaScript

Я не являюсь фронтенд-разработчиком, но иногда возникают задачи быстрого прототипирования WEB-интерфейса применительно к бизнес-приложениям. Специфика отрасли — множество похожих друг на друга сущностей (а значит и интерактивных форм), где применение ООП, а конкретно наследования — очень облегчает жизнь. Я слышал, что в мире WEB для борьбы со сложностью применяют, в основном, композицию, но мне хотелось использовать именно наследование — оно дает более жесткую, связную структуру приложения (в отличие от слабо-связной компонентной), и хорошо отражает предметную область. Задача звучала так — на сервере есть структуры данных, связанные иерархией наследования, необходимо создать в браузере аналогичную иерархию интерактивных форм (страниц), где наследовались бы разметка, стили и поведение — естественно, с возможностью до-пере-определить любую из сущностей.

Ограничения я себе выставил следущие:

  • Cерверную генерацию WEB-интерфейса (с помощью которой легко решалась моя задача) я считаю устаревшей, и придерживаюсь подхода генерации UI строго на клиенте, оставляя серверу лишь хранение данных и тяжелые расчеты (да, я верю в PWA).
  • Интерфейс должен верстаться в текстовой форме, на чистом HTML — я до сих пор не могу смириться с объектными обертками над HTML (типа Dart), так как в свое время намучился с различными обертками над SQL, которые то не поддерживали новейшие возможности языка (например хинты), то были намного медленней и прожорливей, чем ожидалось. Этот импринт сидит во мне прочно, и я наверное всегда буду писать SQL, HTML и CSS — текстом, как в 90-х. И даже обработчики событий я предпочитаю вешать в разметке , а не назначать скриптом. Понимаю, вопрос религиозный, с кем не бывает. С другой стороны, зачем учить новый декларативный язык, если и старый неплох.

Поверхностный поиск готовых решений не дал результатов, времени разбираться с кучей фреймворков не было, и я решил запилить велосипед на чистом JS, тем более, что у него из коробки есть классы с наследованием и модули с инкапсуляцией — почти как у взрослых ЯП. В итоге вырисовывалась такая архитектура:

— Точкой входа в каждую страницу должен стать Javascript, а не HTML. В моем случае страница представлена одним файлом-модулем JS, дефолтно экспортирующем единственный класс, который и определяет разметку, стили и поведение данной страницы.

— Классы страниц могут наследоваться друг-от-друга, и все восходят к одному базовому предку, определяющему содержимое HEAD, базовые стили, базовый контент BODY (колонтитулы, навигацию и т.д.), и базовые функции-обработчики.

— Каждая страница, однажды посещенная, сохраняет в памяти клон дерева DOM вместе с данными, введенными пользователем, и/или полученными с сервера. При повторном заходе на страницу — она восстанавливает DOM (то есть разметку+стили+скрипты+данные). Повторный вход на страницу, заполненную данными, особенно полезен в контексте мобильных устройств, где насыщенные десктопные формы приходится разбивать на множство связанных мелких.

— Все страницы имеют доступ к сохраненнму DOM друг-друга. Таким образом, не требуется иметь общий сессионный объект — каждая форма хранит свои данные сама, лишь добавляя ссылку на себя в объект window.

Я понимаю, что для профессионального «фронтендщика» все перечисленное звучит банально, но я, как джун, был очень обрадован красотой и лаконичностью получившегося решения, и решил оставить эту статью здесь — может еще какому джуну пригодится.

В качестве простого примера — приложение из 3-х страниц. Первая страница домашняя, на второй пользователь загружает файл с данными, а на третьей — вводит формулу и получает результат расчета над данными второй страницы. Далее, как говорится, «talk is cheap, show me the code».

Точка входа в приложение — index.html. Импортируем класс домашней страницы, инстанцируем и отображаем. Также импортируем глобальную функцию навигации, которая используется в разметке примерно так:

Базовый предок всех страниц — содержит методы, возвращающие различные блоки разметки, функции-обработчики (если есть), метод первичной инициализации load(), и метод отображения view(), который, собственно, и занимается сохранением/восстановлением DOM при входе/выходе.

Домашняя страница — переопределяем только метод, возвращающий контент.

Страница загрузки файла — переопределяем контент, добавляем один стиль, вводим новый обработчик fselect(). Обратите внимание, как в разметке назначается обработчик — через глобальную переменную page, которая всегда содержит ссылку на текущую страницу.

Страница расчета — переопределяем контент, меняем заголовок страницы, добавляем обработчик.

Глобальная функция навигации. Если запрошенной страницы нет в памяти — создаем ее из класса, в противном случае активируем. К сожалению, в модуль навигации приходится статически импортировать классы всех страниц. Когда в браузерах будет окончательно имплементирован динамический импорт — останется только функция.

Собственно это все, что я хотел показать — страницы получились достаточно компактными (чем глубже иерархия наследования тем компактнее потомки), стили и функции строго инкапсулированы, разметка и код расположены рядом, в одном файле. Сохранение контекста позволяет строить многостраничные иерерхические формы, мастера-помощники, и т.д.

  • Наследование в JS реализовано синтаксически немного странно, но привыкнуть можно. Отсутствует множественное, но для данной задачи оно вряд-ли потребуется.
  • Трудно объяснить моему редактору, что внутри JS есть куски HTML и CSS, не работают подсказки и автокомплит, но, думаю, это решаемо.

Работающий пример тут.

Читайте так же:  Заявление на расчет неустойки по алиментам образец