2014-10-17 2 views
1
public T getValueByName<T>(String name) 
{ 
    if(T is List) 
     Object containedType = T.WhatGoesHere()? 
... 

В приведенном выше коде, мне нужно знать, если я могу преобразовать список в любой тип списка передается, например, в List<Control>.Какой тип внутри общего контейнера

Есть ли способ опросить общий тип содержимого? Я мог бы получить List<Control>, List<String>, List<Form> и т.д ..

Я мог бы разделить API для возврата списков в отдельном методе, где содержащийся тип передается в, таким образом, требует, чтобы вызывающий использовать один метод для списков и один для простых типов , В любом случае, они должны знать, что вернется, но если есть гладкий способ сделать то, о чем я прошу, я бы предпочел сохранить API просто.

Примечание: это решение, связанное с отсутствием ковариации, потому что, несмотря на наличие неявного оператора преобразования, определенного в содержащемся типе, сбрасывается список из списка в T. Итак, чтобы следовать решению listOfB.Cast<A>();from here, мне нужно знать, что делать (что такое A).

Спасибо!

+2

Вы можете использовать TYPEOF (T), а затем использовать отражение, чтобы получить аргументы родового типа – Charleh

+0

Смотрите эту questi on: http://stackoverflow.com/questions/293905/reflection-getting-the-generic-parameters-from-a-system-type-instance – Charleh

+0

Возможный дубликат [Как получить тип T из общего списка ] (http://stackoverflow.com/questions/557340/how-to-get-the-type-of-t-from-a-generic-listt) –

ответ

4

Вы можете начать поиск с typeof(T), чтобы получить экземпляр System.Type, который представляет T. Как только у вас есть это, вы можете проверить Type.IsGenericType, чтобы узнать, действительно ли он является общим, а затем позвонить Type.GetGenericArguments(), чтобы узнать, какие общие аргументы были использованы.

Например, если T был List<int>IsGenericType бы true и GetGenericArguments() возвратит массив, содержащий один элемент: System.Int32

Например, вот фрагмент кода, который я написал, чтобы увидеть, если данного типа (переменная type) является некоторой реализацией, если IEnumerable<T>, где T неизвестно. Он должен сначала увидеть, если он является общим, то работа, имеет ли это только один аргумент, определить указанным аргументом и посмотреть, если он реализует интерфейс, учитывая, что аргумент:

if (type.IsGenericType) 
{ 
    Type[] genericArguments = type.GetGenericArguments(); 
    if (genericArguments.Length == 1) 
    { 
     Type proposedEnumerable = typeof(IEnumerable<>).MakeGenericType(genericArguments); 
     if (proposedEnumerable.IsAssignableFrom(type)) 
     { 

Для справки см:

+1

Это один из лучших ответов, которые я когда-либо видел на этом сайте. Спасибо! – user1944491

Смежные вопросы