Overriding a subtype's variable with its own subtype

Hey there,

Long story short, I’m building a sort-of framework with which I can create different game types.
The basic structure consists of an abstract Game class, which contains all of the non-game-specific functionality along with an array of [Serializable] abstract Level objects (which contain non-game-specific level info like name and target score to beat). Each of these are subclassed (eg. BP_Game and BP_Level), to implement any game-specific functionality and level information.

Everything works fine, except I’m having to abstract/override the methods which relate to the Level objects in the Game subclasses.

This is a small example of how I have to have it currently (in separate files):

public abstract class Game : MonoBehaviour 
{
	public abstract Level[] GetLevels();
	// ...
}

public class BP_Game : Game 
{
	public BP_Level[] levels;
	public override Level[] GetLevels()
	{
		return this.levels;
	}

	// ...
}

As you can see, it would be the exact same code no matter what subclass, so it would make sense to put it in the abstract base class… I just can’t figure out how to do that! Is it even possible?

I tried adding Level[] levels to the Game class, but the BP_Level[] levels did not override it but rather existed alongside it (calling currentGame.GetLevels() got a nice NullReferenceException because while the subclass’s levels variable was set, it was accessing the base class’s one, which wasn’t).

So… Is it actually possible to do what I’m trying? Or have I just wasted an entire morning :D?

Thanks in advance for any help.

There is no way to override a variable or a function to be/return a different type than what is defined in the base class.

Then again if the return type of GetLevels() is Level, why would it matter what the internal type of the levels is… Anyone using that function wouldn’t see it anyway… Well maybe this was one of the problems you wanted to avoid.

You could use generics if the number of types you need to specify isn’t overwhelming. Though because you can’t make a generic MonoBrhaviour, you’ll have to use an interface.

I’m on mobile so this might not compile but should give you an idea.

public interface IGame<T> {
    T[] GetLevels();
}

public abstract class GameClass<T> : MonoBehaviour, IGame<T> {
     public T[] levels;
     public  T[] GetLevels() {
           return levels;
     }
 }
 
 public class BP_Game : GameClass<BP_Level> {
 }