Создать кортеж, используя список типов данных строки в c# - PullRequest
5 голосов
/ 09 апреля 2020

Мне нужно создать Tuple из списка типов данных в строке, но я не получил никакого решения.

Вот пример того, что я хочу сделать.

string[] dataType = {"int", "float", "datetime"};

//I want to create list like this but dynamically datatype come from db.
//List<Tuple<int, string, string>> list = new List<Tuple<int, string, string>>(); 

List<Tuple<dataType[0],dataType[1], dataType[2]>> list = new List<Tuple<dataType[0],dataType[1], dataType[2]>>();
//Here datatype value is in string so I want to convert string to actual datatype.

Или, если есть альтернативное решение для этого, пожалуйста, направьте меня.

Ответы [ 2 ]

1 голос
/ 10 апреля 2020

Это расширение моих комментариев под вопросом и показывает вам, что я имел в виду.

Нетрудно создать список Tuple динамически из списка типов в строковом формате. Например, используйте отражение:

private Type InferType(string typeName)
{
    switch (typeName.ToLowerInvariant())
    {
        case "int":
            return typeof(int);
        case "float":
            return typeof(float);
        default:
            return Type.GetType($"System.{typeName}", true, true);
    }
}

private object CreateListOfTupleFromTypes(string[] types)
{
    var elementTypes = types.Select(InferType).ToArray();

    // Get Tuple<,,>
    var tupleDef = typeof(Tuple)
        .GetMethods(BindingFlags.Static | BindingFlags.Public)
        .First(mi => mi.Name == "Create"
            && mi.GetParameters().Count() == elementTypes.Length)
        .ReturnType
        .GetGenericTypeDefinition();

    // Get Tuple<int, float, DateTime>
    var tupleType = tupleDef.MakeGenericType(elementTypes);

    // Get List<Tuple<int, float, DateTime>>
    var listType = typeof(List<>).MakeGenericType(tupleType);

    // Create list of tuple.
    var list = Activator.CreateInstance(listType);

    return list;
}

Проблема в том, что список создается с использованием типов, известных только во время выполнения, в вашем коде вы никогда не сможете использовать этот список как строго типизированный список. т.е. List<Tuple<int, float, DateTime>>.

Конечно, вы могли бы упростить жизнь, если список используется в вашем коде, используя ITuple:

var list = new List<ITuple>();
list.Add(new Tuple<int, float, DateTime>(...);

int value1 = (int)list[0][0];
float value1 = (float)list[0][1];
DateTime value1 = (DateTime)list[0][2];

Однако, если вы это сделаете, то нет смысла использовать Tuple. Вам нужен только List<object[]>.

Итак, это возвращает к моему вопросу, для чего нужен список кортежей в вашем коде?

0 голосов
/ 09 апреля 2020

Вы можете использовать dynamic здесь для ваших типов. Например, когда вы читаете три значения из вашей базы данных, вы можете назначать их, не беспокоясь о таких типах, как:

dynamic a = 10;
dynamic b = "Some String";
dynamic c = new DateTime(2020,4,9);

var test = new System.Tuple<dynamic,dynamic,dynamic>(a, b, c);

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

Для создания списка этих кортежей используйте:

var list = new List<System.Tuple<dynamic,dynamic,dynamic>>();

Вы можете получить тип переменной, например a с помощью

a.GetType().ToString();

Я не уверен, что вы можете установить тип переменной на основе строкового значения (вторая часть вашего вопроса).

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