2013-11-30 2 views
6

У меня есть вопрос относительно повышения событий базового класса. Я в настоящее время чтения MSDN C# Руководство по программированию, и я не могу понять одну вещь из следующей статьи:Почему событие базового класса вызывает частный метод?

http://msdn.microsoft.com/en-us/library/vstudio/hy3sefw3.aspx

public void AddShape(Shape s) 
{ 
    _list.Add(s); 
    s.ShapeChanged += HandleShapeChanged; 
} 

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

public void Update(double d) 
{ 
    radius = d; 
    area = Math.PI * radius * radius; 
    OnShapeChanged(new ShapeEventArgs(area)); 
} 

protected override void OnShapeChanged(ShapeEventArgs e) 
{ 
    base.OnShapeChanged(e); 
} 

И здесь мы вызываем метод базового класса OnShapeChanged, который, в успех, будет срабатывать событие. Но событие основано на классе Shape, поэтому как он может получить доступ к методу HandleShapeChanged, который является частным?

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

+0

Возможный дубликат [Вопрос об инкапсуляции с делегатами?] (Http://stackoverflow.com/questions/15586728/encapsulation-issue-with-delegates). Цитируя принятый ответ Эрика Липперта: «Домен доступности метода не ограничивает способ вызова метода. Он ограничивает способ поиска метода по имени». – Brian

ответ

10

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

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

+0

Спасибо! Теперь все ясно. – Kapol

9

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

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

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