简体   繁体   中英

C# Basics - How do interfaces work and calling implemented interface

I desperately need someone to explain me the following case and how it works "under the hood". This would help me understand the concept on a much deeper level.

Unity case:

In Unity3D engine, if we want to detect a click on a UI element, we simply implement one of their premade interfaces called "IPointerClickHandler" to our custom class.

public void OnPointerClick(PointerEventData eventData)
{

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

The script needs to be attached to each individual element, but at the end of the day, it works like a charm.

My case:

This is fascinating for me, because I'm not sure how does Unity know that my class implemented one of its interfaces and calling the appropriate method.

I would like to do a similar trick but I can't figure out how. For example, I would like to notify all classes that implement "IScore" listener which has a method "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);
}``

I would probably need a reference so my idea is to get all references to classes that implement "OnScoreChanged". Is the above example the right approach and how I can make it work? Basically, I want to implement this interface in the class where I need to get notified about new score and completely forget about how this method is called. Is something like this possible?

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

PS I know I can use delegates with events (and then subscribe to this event from other classes), but I'm really curious how can Unity just call the interface method and keep the code much cleaner (so the user doesn't subscribe to its events, etc).

One way to implement this yourself is to derive all your classes from a single base class. This base class will invoke the VIRTUAL function OnWhatever() . [Notice: all your custom Unity component classes are derived from Monobehavior.]

Then when you create your derived classes, you can simply override the virtual OnWhatever() function, with a version specific to that component.


However, if you would like to stick with interfaces only: you can now use GetComponents < T > or GetComponentsInChildren < T > and specify an Interface for the type to find. You can go even "wider", in your interface search, by calling the GetCompoentsInChildren < T > () function on ALL the Scene's "root" Objects .

Then you can simply call/invoke the interface specified OnWhatever() function, for ALL the GetComponents < T > results.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM