Come filtro di oggetti da collezione in base al tipo memorizzato nella variabile

0

Domanda

Ho il seguente gerarchia:

class Animal

class Dog : Animal

class Cat : Animal

Ho un List<Animal> raccolta e vuole fare un metodo che restituisce tutti i gatti o cani. Tuttavia io non riesco a capire come filtrare l'elenco di elementi in base a un tipo di variabile. In questo modo:

int AnimalsOfType(Type animalType)
{
    // Gives error "animalType is a variable but is used like a type".
    return animals.OfType<animalType>().Count;
}
c# casting inheritance list
2021-11-21 02:30:01
2

Migliore risposta

0
using System.Linq;

int AnimalsOfType(Type animalType)
{
    return animals.Count(a => a.GetType() == animalType);
}
2021-11-21 05:33:50

Grazie, ma perché non una variabile tipo di ot Type essere utilizzato come un tipo?
K-RUSHer

Non è possibile passare una variabile di Tipo System.Type come un generico parametro a una funzione generica direttamente. Il motivo è: parametro Generico sono sostituite quando il codice viene compilato Leggere questa risposta che spiega di più
Ibram Reda

Può essere ulteriormente semplificata per animals.Count(a => a.GetType() == animalType);
Sarin

@Sarin sì hai ragione, l'ho modificarla
Ibram Reda
0

Il metodo più efficiente qui è quello di utilizzare MakeGenericMethod e CreateDelegate per creare delegati di metodi generici. È possibile memorizzare nella cache i delegati in un dizionario

static Dictionary<Type, Func<List<Animal>, int>> _methods = new Dictionary<Type, Func<List<Animal>, int>>();

static int CountOfType<T>(List<Animal> source) =>
    source.Count(a => a is T);  
    
int AnimalsOfType(List<Animal> animals, Type animalType)
{
    if(!_methods.TryGetValue(animalType, out var dlgt))
    {
        dlgt = (Func<List<Animal>, int>)
             this.GetType().GetMethod("CountOfType")
                  .MakeGenericMethod(animalType)
                  .CreateDelegate(typeof(Func<List<Animal>, int>)));
        _methods[animalType] = dlgt;
    }
    return dlgt(animals);
}

Non c'è una singola piccola costi di avvio la prima volta che viene chiamato questo metodo, per tipo.

2021-11-21 03:01:30

In altre lingue

Questa pagina è in altre lingue

Русский
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................