Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use abstract classes as function parameters [duplicate]

Tags:

c#

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?

like image 510
Green_qaue Avatar asked Mar 03 '23 05:03

Green_qaue


1 Answers

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

like image 158
Olivier Jacot-Descombes Avatar answered Mar 07 '23 08:03

Olivier Jacot-Descombes