Сгенерированные отражением и общие типы
У меня есть еще один неприятный момент с Reflection.Emit
и типом управления.
Скажем, у меня есть тип с именем MyType
, который определен в динамически сгенерированной сборке.
Вызов MyType.GetMethods()
приводит к NotSupportedException
, что привело меня к написанию моего собственного набора оберток и поисковых таблиц. Тем не менее, то же самое происходит, когда я вызываю GetMethods()
или любые другие методы интроспекции стандартных типовых типов, которые используют мои собственные типы в качестве общих аргументов:
-
Tuple<int, string>
= > отлично работает
-
Tuple<int, MyType>
= > исключение
Я могу получить список методов из определения общего типа:
typeof(Tuple<int, MyType).GetGenericTypeDefinition().GetMethods()
Однако у методов есть общие заполнители вместо фактических значений (например, T1
, TResult
и т.д.), и мне не хочется писать еще один kludge, который отслеживает общие аргументы обратно к их исходным значениям.
Образец кода:
var asmName = new AssemblyName("Test");
var access = AssemblyBuilderAccess.Run;
var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, access);
var module = asm.DefineDynamicModule("Test");
var aType = module.DefineType("A");
var tupleType = typeof(Tuple<,>);
var tuple = tupleType.MakeGenericType(new [] { typeof(int), aType });
tuple.GetProperty("Item1"); // <-- here the error
Итак, вопросы:
- Как определить, безопасен ли тип для вызова
GetMethods()
и аналогичных методов?
- Как получить фактический список методов и их общие значения аргументов, если тип небезопасен?
Ответы
Ответ 1
Я получил ответ в следующем вопросе . Класс TypeBuilder
имеет кучу статических перегрузок, которые выполняют именно ту вещь:
var genericTuple = typeof(Tuple<,>);
var myTuple = genericTuple.MakeGenericType(typeof(int), myType);
var ctor = TypeBuilder.GetConstructor(myTuple, genericTuple.GetConstructors().First());
Странно, нет перегрузки GetProperty
. Однако свойства getters и seters все еще могут быть решены с помощью GetMethod
:
var genericGetter = typeof(Tuple<,>).GetProperty("Item1").GetMethod;
var actual = TypeBuilder.GetMethod(myTuple, genericGetter);
Ответ 2
Я расскажу вам о документации:
Определение типа с отражением Emect
в котором говорится
Хотя TypeBuilder является производным от Type, некоторые абстрактные методы, определенные в классе Type, не полностью реализованы в TypeBuilder. Эти методы TypeBuilder вызывают исключение NotSupportedException. Желаемая функциональность может быть получена путем получения созданного типа с использованием Type.GetType или Assembly.GetType и отражения на извлеченном типе.
Итак:
Как определить, безопасен ли тип для вызова GetMethods() и аналогичных методов на?
Если объект типа является TypeBuilder, или тип относится к любому типу, который является TypeBuilder, тогда это небезопасно.
Как получить фактический список методов и их общие значения аргументов, если тип небезопасен?
Я снова передам вам документацию. Фактически испускайте тип в сборку, а затем вытащите его из сборки.