Ad kdgalla points out, there are a lot of existing tools for “loading” stuff that you might want to consider using. But as for your language question:
It’s generally better to think of “overloaded” functions as being multiple separate functions that happen to have the same name, rather than one function that can do multiple things. Any given piece of code you write is only invoking one specific overload, not “all of them” collectively–and which overload you’re invoking is decided at compile-time, so it can’t depend on run-time data like the dynamic type of an object. Overloads are just a convenience; they don’t let you do things that you couldn’t have done by just making all the overloads into different functions with different names.
And you definitely can’t “override” an inherited function to take different arguments. The core idea of polymorphism is that the subclass can be treated as if it were the base class, which means it needs to be able to do everything the base class can do. If the base class can StartLoading() with no arguments, then every subclass must also be able to StartLoading() with no arguments–otherwise it wouldn’t really be a subtype! The subclass can create new overloads with different arguments (which would be new functions, not overrides), but it can’t remove the ones from the base class. Your example “House” and “Car” classes won’t even compile.
There’s a few general techniques you can apply in a case like this:
- Wrap each of the objects you want to process in an object that encapsulates all of the extra data that they need to do that thing. For instance,
public class HouseLoader : LoadInBackground
{
House housetoLoad;
float height;
int numDoors;
public override IEnumerable StartLoading()
{
return house.StartLoading(height, numDoors);
}
}
The House class would NOT inherit from LoadInBackground; instead, when you want to load a House in the background, you create a HouseLoader object that has a reference to the House plus all the data that the House would need in order to load.
- Figure out a more general argument list that will work for all of your subclasses at once.
Maybe you pass some high-level organizer object like your GameManager as an argument, and each of the subclasses knows how to extract the information it needs from the GameManager.
Or maybe you figure out some way of abstracting the arguments for different subclasses such that you can look at them as being all fundamentally the same. For instance, instead of “numDoors” and “numWheels” you have a “numAccessories” argument that the House uses to create doors and the Car uses to create wheels and so forth. Maybe some of your subclasses ignore some of the arguments. (The more important thing is that the caller needs to know what it should pass as the value of that argument that will somehow be “correct” for all possible subclasses at once–think about where this data is ultimately coming from.)
The really dirty version of this is to use a totally general argument like “object” or “dynamic” that could effectively be anything at all, and the called code is responsible for sorting it out. But this basically loses all the benefits of strong typing and should be treated as a last resort.
- Kind of hacky, not recommended as a general tool, but…the caller can use the keywords “is” and “as” to check the dynamic type of the object, and then apply completely separate logic for each one.
if (thingToLoad is House)
{
House houseToLoad = thingToLoad as House;
houseToLoad.StartLoading(height, numDoors);
}
else if (thingToLoad is Car)
{
Car carToLoad = thingToLoad as Car;
carToLoad.StartLoading(numWheels);
}
This basically loses all the benefits of polymorphism, but if you have a narrow special case then sometimes it’s the easiest thing to do (at least in the short term). It leaves your code very brittle, though.