Can I have variables within an interface?

I’ve created an interface to use with various objects. It’s working so far.

I’ve realized that because of how a particular object in my scene works, it is going to call the function of my interface multiple times in a fraction of a second.
Now that’s not too hard to handle; I can just add a bool, and when the function gets called the script checks that bool. If this function had already been called, it just ignores the function call.

But if I am doing this for every class with this interface, perhaps I should make that bool be a requirement for the interface? That sounds reasonable to me, at least.

But I can’t find anything that explains how to do this, neither do I see examples that show this. I tried just adding the variable all normal like but Unity didn’t like that.
Is this even possible? How do I add a required variable to an interface?

If by “variable” you mean field, pretty sure that isn’t supported, as interfaces are a contract, not an object. But perhaps it is syntactic sugar to trigger the declaration of a variable in the implementing class?

Depending on C# level you are using, interfaces support varying levels of features: methods, properties, etc. I won’t attempt to document what is already well-documented in the learn.microsoft.com site.

This smells like you’re doing premature or speculative optimization.

DO NOT OPTIMIZE “JUST BECAUSE…” If you don’t have a problem, DO NOT OPTIMIZE!

If you DO have a problem, there is only ONE way to find out. Always start by using the profiler:

Window → Analysis → Profiler

Failure to use the profiler first means you’re just guessing, making a mess of your code for no good reason.

Not only that but performance on platform A will likely be completely different than platform B. Test on the platform(s) that you care about, and test to the extent that it is worth your effort, and no more.

https://discussions.unity.com/t/841163/2

Remember that you are gathering information at this stage. You cannot FIX until you FIND.

Remember that optimized code is ALWAYS harder to work with and more brittle, making subsequent feature development difficult or impossible, or incurring massive technical debt on future development.

Don’t forget about the Frame Debugger either, available right near the Profiler in the menu system.

Notes on optimizing UnityEngine.UI setups:

https://discussions.unity.com/t/846847/2

At a minimum you want to clearly understand what performance issues you are having:

  • running too slowly?
  • loading too slowly?
  • using too much runtime memory?
  • final bundle too large?
  • too much network traffic?
  • something else?

If you are unable to engage the profiler, then your next solution is gross guessing changes, such as “reimport all textures as 32x32 tiny textures” or “replace some complex 3D objects with cubes/capsules” to try and figure out what is bogging you down.

Each experiment you do may give you intel about what is causing the performance issue that you identified. More importantly let you eliminate candidates for optimization. For instance if you swap out your biggest textures with 32x32 stamps and you STILL have a problem, you may be able to eliminate textures as an issue and move onto something else.

This sort of speculative optimization assumes you’re properly using source control so it takes one click to revert to the way your project was before if there is no improvement, while carefully making notes about what you have tried and more importantly what results it has had.

“Software does not run in a magic fairy aether powered by the fevered dreams of CS PhDs.” - Mike Acton

Just add a property to your interface, what’s the problem here? Once you add that property you have two ways:

  1. All classes should implement that property if you declare your property as a “contract” (i.e without an implementation) like this:
public interface IInterface
{
    // notice here we don't have an access modifier (private, public...)
    // which means no default implementation => all classes should implement it
    bool MyProperty { get; set; }
}
  1. The new way: Interfaces since C# 8 (Unity 2021?) accepts default interface implementation, which means you don’t have to implement it/change your classes at all:
public interface IInterface
{
    // notice here we DO have an access modifier (public)
    // which means we have a default implementation
    // and no need to implement it in our classes
    public bool MyProperty { get; set; }
}
3 Likes

One method is to have the actual function call merely set a bool “run this for real later”. Then somehow have an update() function which checks the bool, resets it, and runs if needed. Obviously, that complicates the class – normally the game loop has to add whateverclass.update() at the end. Or in Unity I suppose you could make the class a monobehaviour with a lateUpdate() to check all the bools.

This is actually in the official and much-revered Design Pattern book as the Observer pattern. Sounds good, but the “solution” is just to either not worry about it, or add that bool, or have the caller worry about it (like “try to call this only once when you’re done, but calling it over and over is safe”).

Honestly my reasoning here is: I don’t want some ONE script to have forgotten to account for this thing. That sounds like a recipe for me to come back in a few weeks and have some object do some weird stuff that I then have to spend two hours tracking down before I remember some one change I made way back when but didn’t apply it to ALL the scripts using this interface.

It’s happened before.

I know most people these days advocate staying away from inheritance but honestly, this is exactly the sort of thing it was invented for and exactly the type of situation in which I would use it myself. Create an abstract class that implements the interface and implements the default public method. Internally it performs the bool check and calls a protected abstract method that must be implemented in further derived concrete classes.

public interface IInterface
{
    public bool SomeFlag { get; }
    public void PublicFunction();
}

public abstract class AbstractFoo : IInterface
{
    public abstract bool SomeFlag { get; }

    public void PublicFunction()
    {
        if (SomeFlag)
            ClassSpecificLogic();
    }

    protected abstract void ClassSpecificLogic();
}

public class ConcreteFoo : AbstractFoo
{
    public override bool SomeFlag => throw new System.NotImplementedException();

    protected override void ClassSpecificLogic()
    {
        throw new System.NotImplementedException();
    }
}

From here you can still instantiate a concrete class as an instance of IInterface so it’ll work like before.

3 Likes

I’m not seeing how inheritance is relevant. Sure, the standard approach is for the class to have a hidden flag which calls to doThisThing() secretely examines, but any class can do that. All inheritance adds is being able to easily swap in alternate implementations. I don’t see OP having a problem with that.

But this sidesteps the problem of needing an extra call. If you want a hidden bool to only run this thing the first call each frame, someone is going to somehow tell the class “new frame”. Somewhere in the client code there needs to be an extra call like c1.preUpdate() to set ranThisFrame=false.

Or, I suppose it could be seamless if the class secretely records the last time it was called, and only runs it again if the current time is 0.005 past that (but then you’ve got to worry about pausing the game).