Создание универсального типа для кортежей - PullRequest
4 голосов
/ 13 июня 2011

Я четко установил, как сделать общий кортеж следующим образом, когда количество элементов известно заранее ...

        Type t = typeof(Tuple<,,>);
        Type[] keys = new Type[] { typeof(string), typeof(string), typeof(int) };
        Type specific = t.MakeGenericType(keys);

но что если количество объектов в массиве "keys"переменная?Как начать шарик с начального присвоения «т»?

Ура.Craig

Ответы [ 2 ]

8 голосов
/ 13 июня 2011

Лично у меня был бы массив определений универсального типа:

Type[] tupleTypes = {
    typeof(Tuple<>),
    typeof(Tuple<,>),
    typeof(Tuple<,,>),
    typeof(Tuple<,,,>),
    typeof(Tuple<,,,,>),
    typeof(Tuple<,,,,,>),
    typeof(Tuple<,,,,,,>),
    typeof(Tuple<,,,,,,,>),
};

Вы могли бы сделать это в коде, но это было бы немного больно ...вероятно что-то вроде:

Type[] tupleTypes = Enumerable.Range(1, 8)
                              .Select(x => Type.GetType("System.Tuple`" + x)
                              .ToArray();

Или избегая массива:

Type generic = Type.GetType("System.Tuple`" + keys.Length);
Type specific = generic.MakeGenericType(keys);
2 голосов
/ 07 октября 2012

Еще один способ построения tupleTypes через Tuple.Create:

// once
Type[] tupleTypes = typeof(Tuple).GetMethods(BindingFlags.Public | BindingFlags.Static)
    .Where(mi => mi.IsGenericMethod && mi.Name == "Create")
    .Select(mi => mi.ReturnType.GetGenericTypeDefinition())
    .Distinct() // make sure there is no duplicated return types
    .OrderBy(t => t.GetGenericArguments().Length)
    .ToArray(); // expect start from Tuple<>

// instant type creation
Type tupleType = tupleTypes[types.Length-1].MakeGenericType(types);

Конечно, ожидается, что класс System.Tuple будет содержать статические методы Create, которые производят только Tuple <...>.

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