我正在将现有的类库移植到 Silverlight。我经常使用 lambda 表达式编译,现在我正因为它而遇到安全问题。
特别是,如果来自客户端 SL 应用程序的匿名类参与 lambda 表达式,我无法编译它:我得到一个MethodAccessException
带有以下堆栈跟踪的:
MethodBase.PerformSecurityCheck(Object obj, RuntimeMethodHandle method, IntPtr parent, UInt32 invocationFlags)
RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
MethodBase.Invoke(Object obj, Object[] parameters)
Expression.Lambda(Type delegateType, Expression body, IEnumerable<T> parameters)
Expression.Lambda(Type delegateType, Expression body, ParameterExpression[] parameters)
Expression.Lambda(Expression body, ParameterExpression[] parameters)
我尝试InternalsVisibleTo
在客户端 SL 应用程序中使用向我的类库公开匿名类,但它没有帮助。实际上它应该有帮助,但我不明白为什么它没有。
有任何想法吗?
更新:
我发现问题不在于 lambda 表达式,而在于动态泛型方法调用:
如果我们在类库中有以下代码:
public class LibClass
{
public static void StaticReceive<T>(T x)
{
Process<T>(x);
}
public static void DynamicReceive(object x)
{
typeof(LibClass).GetMethod("Process", BindingFlags.NonPublic | BindingFlags.Static)
.MakeGenericMethod(x.GetType())
.Invoke(null, new object[] { x });
}
static void Process<T>(T x)
{
// some work with typed x
}
}
我们从应用程序中调用 StaticReceive 方法,如下所示:
class InternalClass { }
void MethodInUserApp()
{
var x = new InternalClass();
LibClass.StaticReceive(x);
}
它工作正常,但如果我们使用DynamicReceive
,它会失败。看起来 CLR 将方法中的x
参数Process
视为 type InternalClass
,而不是 generic T
,并且由于InternalClass
库无法访问,因此禁止其调用。
它看起来像一个错误,不是吗?