Как мне создать динамический тип List <T> - PullRequest
8 голосов
/ 25 марта 2012

Я не хочу, чтобы мой список был фиксированного типа.Скорее я хочу, чтобы создание List зависело от типа переменной.Этот код не работает:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Generic;
namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {

            string something = "Apple";

            Type type = something.GetType();

            List<type> list = null;

            Console.ReadKey();

        }
    }
}

Кто-нибудь может сказать мне, какие изменения мне нужно внести, чтобы заставить его работать правильно?Я хочу, чтобы создание list зависело от типа переменной something

Ответы [ 4 ]

35 голосов
/ 25 марта 2012
string something = "Apple";
Type type = something.GetType();
Type listType = typeof(List<>).MakeGenericType(new [] { type } );
IList list = (IList)Activator.CreateInstance(listType);

Так создается список статически неизвестного типа.Но обратите внимание, что вы не можете упоминать тип списка во время выполнения статически.Вы должны использовать неуниверсальный тип или даже объект.

Не зная больше о том, чего вы хотите достичь, это лучшее, что вы можете сделать.

6 голосов
/ 25 марта 2012

Я хочу безопасность типов, но мне нужна безопасность динамических типов.

Если вы хотите иметь безопасность типов во время выполнения, вы можете создать List<T>, используя отражение (см. Ответ пользователя) илиdynamic, а затем обрабатывать его как неуниверсальный IList.

Используя dynamic, это будет выглядеть примерно так:

static List<T> CreateListByExample<T>(T obj)
{
    return new List<T>();
}

…

object something = "Apple";

IList list = CreateListByExample((dynamic)something);

list.Add(something); // OK

list.Add(42);        // throws ArgumentException
1 голос
/ 25 марта 2012

Динамика и рефлексия работают нормально - , но при этом снижается производительность - и теряется строгая типизация, дизайн / четкость кода и т. Д.
т.е. вы всегда должны пытаться решать проблемы/ o it - если вы можете, ваш код позволяет это ...
Итак, и (примечание) в зависимости (очень) от вашего конкретного кода , потребности,
Вы также можете использовать «трюк», чтобы «вывести» тип и сделать его универсальным ...

class Program
{
    static void Main(string[] args)
    {
        string something = "Apple";
        int test = 5;
        var list = something.GetList();
        var listint = test.GetList();
        Console.WriteLine(list.GetType());
    }
}
static class Extension
{
    public static List<T> GetList<T>(this T value)
    {
        return new[] { value }.ToList();
    }
}

... т.е. если у вас есть значение для переменной и перед вводом«общий контекст»,
вы можете использовать расширения (которые очень полезны для этого), и позволить ему выводить тип и тип списка для вас
ПРИМЕЧАНИЕ: эта «работа вокруг», к сожалению, не всегда панорамируетсяи когда ваш код «слишком динамичен» (я знаю, что он не слишком «точен», но выходит за рамки этого), и если он зависит от типов, вызванных отражением и т. д.
т.е.Решение, это всего лишь пример, вам нужно было бы потеть немного :), чтобы сделать этоработать для вас - например, вам может потребоваться тип оболочки здесь и там, и очевидно, что создание списка таким способом может оказаться не тем, что вам нужно и т. д.

0 голосов
/ 25 марта 2012

Компилятор должен знать универсальный тип T во время компиляции. Так что нет, ты не можешь этого сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...