2016-06-29 3 views
0

Например, я понимаю, что я не могу передать событие методу или конструктору, но я не понимаю, почему я не могу. Что отличает событие от собрания делегатов?Почему событие не является объектом первого класса в C#

+1

@cFrozenDeath Я уверен, что я не понимаю, что такое событие. Если бы я это сделал, я бы не стал задавать этот вопрос. –

+0

Ради будущих читателей вы могли бы добавить фрагмент кода, демонстрирующий это поведение? –

ответ

6

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

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

От Jon Skeet «s C# in Depth: Delegates and Events

+0

Это просто указание, что события не являются объектами первого класса. Вопрос спрашивает, почему они не являются, которые, как предпосылка, предполагают, что это не так. – Servy

+1

@Servy Я думаю, что знание того, что события - это пары методов, каким-то образом объясняет, почему? Если вы тогда захотите узнать, почему они такие, то я бы сказал, что основной причиной является инкапсуляция. Вызов события может выполняться только внутри класса, объявившего это событие. Можно было бы более или менее эмулировать события в C#, имея частный член делегирования с помощью пары общих методов доступа. События в C# дают соответствие этому (а не людям, создающим похожие, но разные способы решения этой проблемы) и добавляют какой-то синтаксический сахар, поэтому мы все можем набрать немного меньше. – withakay

+1

Это оправдывает, почему события имеют поддержку столько, сколько они делают. Вопрос в том, почему он останавливается там и почему вы не можете, например, передать событие в качестве параметра методу. Вы могли бы абсолютно создать язык для этого, учитывая, что событие было инкапсулировано. Ваше оправдание тому, почему события не могут быть поддержаны более глубоко, вместо этого поддерживает то, что они могут быть (хотя никоим образом не рассматривая, почему они не были). – Servy

1

События, объявлен в классе, чтобы объекты внешних по отношению к классу, чтобы быть прикрепить к событию и получать уведомления об изменениях, происходящих в этом классе.

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

Чтобы предотвратить это события имеют особые правила доступа, которые позволяют только класс, который Объявляет событиене даже свои собственные подклассы), чтобы запустить событие.

Следовательно, для этой безопасности события не являются первоклассными гражданами .NET Framework.

+1

Хотя я считаю, что ответ @ inakay является технически правильным ответом, я считаю, что ваш гораздо лучший практический пример того, почему вы не можете проходить событие вокруг. –

+0

Это совершенно неверно. Вы можете сделать событие гражданином первого класса, не позволяя им быть вызванным извне этого типа. По этой логике частное поле не должно быть гражданином первого класса, поскольку к нему нельзя получить доступ за пределами класса или к собственному сетевому устройству или к чему-либо еще, имеющему область видимости (т. Е. В основном все). – Servy

+1

@Servy - Я не согласен. События очень разные, чтобы сравнивать их с частными полями. Вы можете передать значение/ссылку частного поля и использовать его со 100% своих функций, но вы не можете сделать это с событием. – Enigmativity

Смежные вопросы