Основная проблема здесь в том, что тип, передаваемый в System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
, либо не является общедоступным, либо имеет конструктор, который не является общедоступным.
Теперь - учитывая простоту вашего примера кода и глубинутрассировка стека, я полагаю, проблема не в plan
, а в выражении в plan
(поскольку вы говорите в своем комментарии к ответу Марка, что это тоже выражение), которое ссылается на тип, который затем ограничивается.
Выражение, которое здесь является источником ошибки, это ConstantExpression
, который должен иметь ограниченный тип.
Единственное, что сбивает с толку, это то, что аргумент типа, который AddGlobal
переходит к Activator.CreateInstance
is StrongBox<T>
, который является общедоступным и имеет открытый конструктор - что подразумевает, что эта ошибка должна быть невозможной.
Возможно, однако, есть что-то скрытое, связанное с StrongBox<T>
, что мыне могу видеть через Reflector.
Итак, я бы посмотрел на все дерево выражений, представленное plan
, и исследовал всетипы, указанные в ConstantExpression
s, чтобы гарантировать, что они все доступны.Если после этого все типы показаны как доступные, эта ошибка по-прежнему возникает, то это может быть ошибка в платформе.
Однако - я бы подумал, что такая ошибка уже была бы найдена для чего-топросто как ConstantExpression
!
РЕДАКТИРОВАТЬ (замена предыдущего редактирования) С ОТВЕТОМ
У меня есть, и этоочень тонкая проблема.Вы можете воспроизвести этот небольшой фрагмент кода на странице aspx, настроенной для работы со средним доверием:
Type t = typeof([any type you fancy]);
Expression expr = Expression.Constant(t);
var lambda = Expression.Lambda<Func<Type>>(expr);
var del = lambda.Compile();
Response.Write(del().ToString());
Итак, в предоставленном вами коде это выражение представляет второй аргумент ChangeType
(мне понадобилось некоторое время, чтобы понять, что это метод Sub Sonic), который выглядит как Type
(код не виден, но я думаю, что это разумное предположение!).
Этозапекается в выражении как ConstantExpression
экземпляра Type
.Не спрашивайте, как я сузил параметр - много работы по сканированию стека и отражателю;)
Как упоминалось в первой половине моего ответа, трудно понять, как код, используемый компилятором дерева выражений, можеткогда-либо создавать исключение MethodAccessException, так как оно всегда обращается к общедоступному ctor типа StrongBox<T>
.
Однако это будет расстроено, если тип, переданный как универсальный, не является общедоступным.«Но подождите, - говорите вы, - Type
общедоступно!».
Может быть, но экземпляр Type
, возвращаемый во время выполнения из typeof()
или GetType()
, не является - этоэкземпляр RuntimeType
- который является внутренним .
. Именно поэтому приведенный выше фрагмент кода также вызовет ту же ошибку.
Исправление
Измените код, который выдает аргумент Type
для ChangeType(,)
, с
Expression.Constant([type])
(что я почти гарантирую, что это так на данный момент) на
Expression.Constant([type], typeof(Type))
Это работает, потому что вы явно указываете компилятору использовать общедоступную Type
для константы вместо отраженного типа RuntimeType
.
Вы можете проверить это исправление, применивэто к моему примеру кода в предыдущем блоке и повторного запуска.