I need help understanding the use of abstract classes. I have an abstract class called WorldObject
:
public abstract class WorldObject
{
public Vector3 position;
}
I have many classes that inherit from this, for example Building
and Tree
.
I want to create a method that loops through a List
of WorldObjects
, and return the closest one to me.
I want to be able to use this method with all my types of WorldObjects
, but I can't get it to work:
public List<Building> buildings = new List<Building>();
public List<Tree> trees= new List<Tree>();
private void GoToClosestBuilding()
{
var target = GetClosestWorldObject(buildings); //Error: Cannot convert building to WorldObject
}
Vector3 GetClosestWorldObject(List<WorldObject> objects)
{
//...
}
When I try to pass my Building
or Tree
lists to my method, it returns an error that it cannot convert between Building
and WorldObject
, and so on.
How can I structure my code so that something like this would work?
A List<Building>
is not assignment compatible to a List<WorldObject>
because then you could do
List<WorldObject> worldObjects = buildings; // Not possible!
worldObjects.Add(tree); // Legal
worldObjects.Add(tree);
is perfectly legal. But as worldObjects
would reference a list of buildings, you would not be allowed to add it a tree!
However, you can change the signature of the method to
Vector3 GetClosestWorldObject(IEnumerable<WorldObject> objects)
{
...
}
Now, this works
var target = GetClosestWorldObject(buildings);
because the enumerable is declared as
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
The out
keyword states that T
occurs only in out-positions, i.e. as return value or as out parameter. This makes the type co-variant.
See also: - Covariance and Contravariance (C#) - Microsoft Docs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With