Проверка подкласса по конкретному индексу списка - PullRequest
0 голосов
/ 25 марта 2011

Привет, мне интересно, как бы вы проверили, равен ли объект в определенном месте в Списке чему-либо.

У меня есть 3 подкласса "Корабль", они называются "Враг", "Враг2", "Игрок" Все они сохранены в Списке, который я называю «Корабли»

Мне интересно, как вы могли бы проверить в списке, что элемент в индексе относится к одному из перечисленных выше. Это довольно сложно объяснить, я попытаюсь объяснить в коде.

for (int i = 0; i < Game1.Ships.Count; i++)
    {
    if(Game1.Ships.ElementAt(i) == "Enemy")
        Enemy e = Game1.Ships.ElementAt(i);
        if (this.collisionBox.Intersects(e.collisionBox))
        {
            e.Destroy(false);
            //Execute Destory(bool).
        }
    }
    else
        i++;
        //Skip to next item.

Это примерно то, что я пытаюсь сделать, очевидно, мне нужно проверить, что это не игрок. И я также должен был бы сделать тот же цикл для Enemy2. Заметьте, однако, что у «Корабля» по умолчанию нет Destroy (bool), он существует только в «Enemy» и «Enemy2».

Ответы [ 4 ]

3 голосов
/ 25 марта 2011

просто используйте is:

for (int i = 0; i < Game1.Ships.Count; i++)
{
    if(Game1.Ships.ElementAt(i) is Enemy)
    {
        Enemy e = (Enemy)Game1.Ships.ElementAt(i);
        if (this.collisionBox.Intersects(e.collisionBox))
        {
            e.Destroy(false);
            //Execute Destory(bool).
        }
    }
    else
        i++;
        //Skip to next item.
}
0 голосов
/ 25 марта 2011

Или LINQish:

var enemiesToDestroy = from enemy in Game1.Ships.OfType<Enemy>()
                       where this.collisionBox.Intersects(enemy.collisionBox)
                       select enemy;
enemiesToDestroy.ToList().ForEach(enemy => enemy.Destroy(false));

Если вы хотите избавиться от преобразования ToList (), определите следующий метод расширения

public static void ForEach<TSource>(this IEnumerable<TSource> source, Action<TSource>   action)
{
    foreach (TSource element in source)
        action (element);
}

И используйте его следующим образом:

enemiesToDestroy.ForEach(enemy => enemy.Destroy(false));
0 голосов
/ 25 марта 2011

Вы абсолютно не хотите использовать ElementAt() подобным образом, так как он выполняет итерацию в начале последовательности каждый раз. Я бы предложил использовать петлю foreach и OfType<>() вместо:

foreach (var e in Game1.Ships.OfType<Enemy>())
{
    if (this.collisionBox.Intersects(e.collisionBox))
        e.Destroy(false);
}

Или, если Game1.Ships реализует ICollection, вы можете использовать цикл for и заменить .ElementAt(i) на [i]:

for (int i = 0; i < Game1.Ships.Count; i++)
{
    var e = Game1.Ships[i] as Enemy;
    if (e != null)
        if (this.collisionBox.Intersects(e.collisionBox))
            e.Destroy(false);
}
0 голосов
/ 25 марта 2011

и рассмотрим

 foreach (var e in Game.Ships.OfType<IDestroy>())
     e.Destroy()

Казалось бы, неплохая стратегия, когда

"Корабль" по умолчанию не имеет Destroy (bool), он существует тольков "Enemy" и "Enemy2"

Если вы не можете / не будете добавлять интерфейс, чтобы было легче выбирать типы кораблей, тогда вы можете прибегнуть к

var destroyables = Game.Ships
           .OfType<Enemy>()
     .Concat(
           Game.Ships.OfType<Enemy2>());

DoМне нужно указать, какой метод будет иметь мой голос?

...