Question Comment obtenir le type de T d'un membre d'une classe ou d'une méthode générique?


Disons que j'ai un membre générique dans une classe ou une méthode, donc:

public class Foo<T>
{
    public List<T> Bar { get; set; }

    public void Baz()
    {
        // get type of T
    }   
}

Quand j'instancie la classe, le T devient MyTypeObject1, donc la classe a une propriété de liste générique: List<MyTypeObject1>. La même chose s'applique à une méthode générique dans une classe non générique:

public class Foo
{
    public void Bar<T>()
    {
        var baz = new List<T>();

        // get type of T
    }
}

Je voudrais savoir, quel type d'objets contient la liste de ma classe. Donc, la propriété de liste appelée Bar ou la variable locale baz, contient quel type de T?

Je ne peux pas le faire Bar[0].GetType(), car la liste peut contenir zéro élément. Comment puis-je le faire?


549
2018-02-17 15:24


origine


Réponses:


Si je comprends bien, votre liste a le même paramètre de type que la classe de conteneur elle-même. Si c'est le cas, alors:

Type typeParameterType = typeof(T);

Si vous êtes dans la situation chanceuse d'avoir object en tant que paramètre de type, voir La réponse de Marc.


554
2018-02-17 15:27



(note: je suppose que tout ce que vous savez est object ou IList ou similaire, et que la liste pourrait être de n'importe quel type à l'exécution)

Si vous savez que c'est un List<T>, puis:

Type type = abc.GetType().GetGenericArguments()[0];

Une autre option consiste à regarder l'indexeur:

Type type = abc.GetType().GetProperty("Item").PropertyType;

En utilisant nouveau TypeInfo:

using System.Reflection;
// ...
var type = abc.GetType().GetTypeInfo().GenericTypeArguments[0];

461
2018-02-17 15:26



Avec la méthode d'extension suivante, vous pouvez vous échapper sans réfléchir:

public static Type GetListType<T>(this List<T> _)
{
    return typeof(T);
}

Ou plus général:

public static Type GetEnumeratedType<T>(this IEnumerable<T> _)
{
    return typeof(T);
}

Usage:

List<string>        list    = new List<string> { "a", "b", "c" };
IEnumerable<string> strings = list;
IEnumerable<object> objects = list;

Type listType    = list.GetListType();           // string
Type stringsType = strings.GetEnumeratedType();  // string
Type objectsType = objects.GetEnumeratedType();  // BEWARE: object

41
2017-09-23 10:05



Essayer

list.GetType().GetGenericArguments()

26
2018-02-17 15:26



C'est un travail pour moi. Où myList est une sorte de liste inconnue.

IEnumerable myEnum = myList as IEnumerable;
Type entryType = myEnum.AsQueryable().ElementType;

12
2018-05-18 10:01



Considère ceci: Je l'utilise pour exporter 20 listes tapées de la même manière:

private void Generate<T>()
{
    T item = (T)Activator.CreateInstance(typeof(T));

    ((T)item as DemomigrItemList).Initialize();

    Type type = ((T)item as DemomigrItemList).AsEnumerable().FirstOrDefault().GetType();
    if (type == null) return;
    if (type != typeof(account)) //account is listitem in List<account>
    {
        ((T)item as DemomigrItemList).CreateCSV(type);
    }
}

9
2018-03-29 19:36



Si vous n'avez pas besoin de toute la variable Type et que vous voulez simplement vérifier le type, vous pouvez facilement créer une variable temp et utiliser l'opérateur.

T checkType = default(T);

if (checkType is MyClass)
{}

6
2018-05-08 10:21



le GetGenericArgument() la méthode doit être définie sur le type de base de votre instance (dont la classe est une classe générique myClass<T>). Sinon, il renvoie un type [0]

Exemple:

Myclass<T> instance = new Myclass<T>();
Type[] listTypes = typeof(instance).BaseType.GetGenericArguments();

5
2017-07-29 14:26