Flight
Flight

Reputation: 41

How to count members with a specified subclass from a List?

I have an Enemy class.

There are classes that inherit from it, like Soldier, Captain, and so on.

I have a List that contains all enemies.

If I wanted to count how many are of type Soldier, I could do:

List<Enemy> enemies;

public int CountSoldiers()
{
    int count = 0;
    foreach (Enemy enemy in enemies)
    {
        if (enemy is Soldier)
        {
            count++;
        }
    }
    return count;
}

But there are many types of enemies, and I would like to count by any type. Is there a way to pass an enemy or its type as a parameter so it is counted?

That would be an example code, but it does NOT work:

public int CountEnemyType(System.Type type)
{
    int count = 0;
    foreach (Enemy enemy in enemies)
    {
        if (enemy is type)
        {
            count++;
        }
    }
    return count;
}

Upvotes: 1

Views: 350

Answers (2)

Klaus G&#252;tter
Klaus G&#252;tter

Reputation: 11997

A simple approach without the need to define any additional methods:

var soldierCount = enemies.Count(e => e is Soldier);

Upvotes: 0

Joel Coehoorn
Joel Coehoorn

Reputation: 416039

This will work:

public int CountEnemiesByType<T>()  where T : Enemy
{
    return enemies.OfType<T>().Count();
}

Call it like this:

int soldierCount = CountEnemiesByType<Soldier>();

See it work here:

https://dotnetfiddle.net/eEeElR

I'm also inclined to build it more like this:

public int CountEnemiesByType<T>(IEnumerable<Enemy> enemies)  where T : Enemy
{
    return enemies.OfType<T>().Count();
}

But even more this seems like something where we should be using composition instead of inheritance: an enemy has a type, rather than is a type.

Upvotes: 4

Related Questions