Реализация общего вывода типа в C # рефлексивно - PullRequest
2 голосов
/ 21 декабря 2010

Мне нужно сделать какой-то общий вывод типа для реализации языка сценариев, и мне интересно, если я упускаю какой-то простой подход. На данный момент позвольте мне спросить о структуре типов и игнорировать границы. Для иллюстрации приведем глубоко вложенный пример:

T foo<T>( List<List<List<T>>> ) {...}

Теперь я хочу проверить, могу ли я передать строку аргументов типа:

List<List<List<string>>>

к этому методу, а затем используйте MakeGenericMethod () с обнаруженным типом параметра, чтобы преобразовать и вызвать его.

Из того, что я могу сказать, даже если мне удастся создать открытый универсальный тип, эквивалентный аргументу foo (т.е. List<List<List<T>>>), он не будет тестироваться с помощью isAssignable (). Я не уверен, есть ли какая-то хитрость для проверки присваиваемости открытых универсальных типов или просто не поддерживается. Я думаю, что если я должен, я могу сделать это напрямую.

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

Любой совет от кого-то, кто уже прошел через это безумие, был бы оценен:)

спасибо, Пэт Нимейер

1 Ответ

1 голос
/ 22 декабря 2010

Итак, я полагаю, что я реализовал это успешно, исходя из предположения, что вы должны повторно определить типы для сравнения присваиваемости. Насколько я могу судить, нет даже способа извлечь базовый тип из универсального типа для самостоятельной проверки присваивания. Итак, в итоге я использовал GetGenericArguments для параллельного прохождения типа параметра метода и типа аргумента, выполняя проверки работоспособности на каждом шаге (совпадение количества универсальных параметров и т. Д.) И однажды в конечном итоге находя параметр «голого» универсального типа, отмечая соответствующий (предполагаемый) тип в аргументе. Вы можете определить, что вы нашли параметр типа, используя IsGenericParameter. Затем, как ни странно, вы должны сохранить эти типы в стороне и использовать их для создания экземпляра метода, передавая их в определенном порядке в MakeGenericMethod. Порядок предоставляется для вас свойством самого типа, GenericParameterPosition, (опять же, странно), но простой порядок сортирует их. После этого все нормальные правила, кажется, применяются.

-Пат

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