Основы C # - Как работают интерфейсы и как вызывать реализованный интерфейс - PullRequest
0 голосов
/ 24 декабря 2018

Мне отчаянно нужен кто-то, чтобы объяснить мне следующий случай и как он работает "под капотом".Это помогло бы мне понять концепцию на более глубоком уровне.

Случай Unity:

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

public void OnPointerClick(PointerEventData eventData)
{

  // Do whatever you want in here, when you detect click on UI element
}

Скрипт необходимо прикрепить к каждому отдельному элементу, но в конце концов он работает как шарм.

Мой случай:

Для меня это увлекательно, потому что я не уверен, как Unity узнает, что мой класс реализовал один из своих интерфейсов и вызвал соответствующийМетод.

Я хотел бы сделать подобный трюк, но я не могу понять, как.Например, я хотел бы уведомить все классы, которые реализуют прослушиватель «IScore», который имеет метод «OnScoreChanged (float newScore)»;

public float Score;

public interface IScore {

    void OnScoreChanged(float newScore);
}



public void SetScore(int newScore) {

    Score = newScore;
   //Notify all classes that implement IScore interface

   // .OnScoreChanged(newScore);
}``

Мне, вероятно, понадобится ссылка, поэтому моя идея состоит в том, чтобы получить всессылки на классы, которые реализуют "OnScoreChanged".Является ли приведенный выше пример правильным подходом и как я могу заставить его работать?По сути, я хочу реализовать этот интерфейс в классе, где мне нужно получать уведомления о новых результатах и ​​полностью забыть о том, как вызывается этот метод.Возможно ли что-то подобное?

    public class MyClassB: IScore {
        public void OnScoreChanged(float newScore)
        {
            // This just got called after score 
//changed..and without any additional implementation!
        }
    }

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

1 Ответ

0 голосов
/ 25 декабря 2018

Один из способов реализовать это самостоятельно - извлечь все ваши классы из одного базового класса.Этот базовый класс вызовет функцию VIRTUAL OnWhatever().[Примечание: все ваши пользовательские классы компонентов Unity являются производными от Monobehavior.]

Затем, когда вы создаете производные классы, вы можете просто переопределить виртуальную функцию OnWhatever() с версией, специфичной для этого компонента.


Однако, если вы хотите придерживаться только интерфейсов: теперь вы можете использовать GetComponents < T > или GetComponentsInChildren < T > и указать Interface для типа, который нужно найти.В поиске интерфейса вы можете пойти еще шире, вызвав функцию GetCompoentsInChildren < T > () на ВСЕХ «корневых» объектах Сцены .

Затем вы можете просто вызвать / вызвать интерфейсуказанная OnWhatever() функция, для ВСЕХ GetComponents < T > результатов.

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