Как сделать публичные методы видимыми только в самом классе и классе, владеющем объектом в C #? - PullRequest
8 голосов
/ 04 января 2012

Мой коллега и я столкнулись с этим, когда изучали список вызовов делегата. Если вы создаете событие, скажем, в классе X, то вы можете получить доступ к открытым методам штрафа события из этого класса. Но (и, пожалуйста, игнорируйте такие вещи, как, например, почему у вас есть публичный доступ к ученикам, это не то, о чем мы просим!), Если у нас есть класс Y, создающий экземпляр X, и доступ к событию внутри X, это не может вызовите любой из открытых методов, таких как GetInvocationList () события. Мы хотели знать, как это работает. Вот пример кода (прочитайте комментарии, чтобы понять, что мы имеем в виду):

    public class X
    {
        public delegate void TestMethod();

        public event TestMethod testMethod;

        private void rubbish()
        {
            // can access testMethod.GetInvocationList() fine here
            testMethod.GetInvocationList(); 
        }
    }

    public class Y
    {
        public Y()
        {
            X x = new X();
            x.testMethod += this.test;

            // here it says testMethod can only appear on the left hand side of += or -=
            // why is this? (i.e. the below line is invalid)
            x.testMethod.GetInvocationList(); 
        }

        public void test()
        {
        }
    }

Из любопытства, как вы этого добиваетесь и в чем причина того, что эта функция доступна?

Большое спасибо Амит

Ответы [ 4 ]

9 голосов
/ 04 января 2012

Это то, что делает ключевое слово event;это модификатор, который ограничивает операции, отличные от подписки, для класса-владельца.Если вы удалите ключевое слово event, вы получите простой делегат, который могут вызывать клиенты вне класса, например, метод GetInvocationList().

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

1 голос
/ 04 января 2012

Я нашел некоторую информацию об этом - доступ к нему вне объявленного класса очень ограничен - ниже с сайта MSDN ( Учебное пособие по событиям ).

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

Создайте нового делегата в этом поле.

Удалить делегата из (возможно, составного) поля.

Это делается с помощью операторов + = и - =. Чтобы начать получать событие вызовы, клиентский код сначала создает делегат типа события это относится к методу, который должен быть вызван из события. затем он составляет этот делегат на любые другие делегаты, что событие может быть подключен к использованию + =.

Более подробная информация доступна по ссылке.

0 голосов
/ 04 января 2012

Думайте о делегатах отдельно от событий

хммм ... я собираюсь взять WAG здесь.

Поместите вашу делегатскую декларацию в ваше пространство имен вне любых классов.

  • В классе X создайте экземпляр этого делегата (не говоря уже о событии) и зарегистрируйте "handlers:" (я использую этот термин "по желанию")

  • Создайте открытый метод или свойство, чтобы класс Y мог получить (ссылка к) делегат и, следовательно, его список вызовов.

  • Теперь вы можете делать все, что вы хотите в классе Y. Вы даже можете создать «зеркальное» событие в классе Y с использованием списка вызовов делегата класса X.

0 голосов
/ 04 января 2012

afaik только при использовании событий, если вы удалите «событие» в строке, вы можете использовать метод просто отлично

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...