Dan*_*tle 6 c# aop spring.net aopalliance
我在C#中有一个非常有趣的AOP体验.我有一个带有返回类型List的函数,它被截获,这一切都很好.然而,拦截器函数是验证器样式函数,可以通过调用并返回布尔值false来阻止实际函数.
所以代码看起来有点像这样:
List<Update> updates = Manager.ValidateAndCreate();
// protected void Save(List<Update> updates) { ....
Save(updates);
Run Code Online (Sandbox Code Playgroud)
方法拦截器如下所示
public class ExceptionAdvice : AopAlliance.Intercept.IMethodInterceptor {
public object Invoke(AopAlliance.Intercept.IMethodInvocation invocation) {
if (isValid(invocation)) {
return invocation.Proceed();
} else {
return false;
}
}
private bool isValid( ...
}
Run Code Online (Sandbox Code Playgroud)
现在验证失败后,更新的值实际上是布尔值而不是列表,我认为这里会出现某种运行时错误但是没有,所以:
updates.GetType().Name == "Boolean"
Run Code Online (Sandbox Code Playgroud)
但:
updates is bool == false
Run Code Online (Sandbox Code Playgroud)
因此,save仍将接受其变更的更新列表,并会在您尝试使用它时稍后进行投诉.
那么在C#等类型安全的语言中,这怎么可能呢?顺便说一句,它是春天的.
编辑:这也是编译,它确实有效,我现在已经介绍了几次.
我相信这是可能的,因为Spring.Net在运行时发出代理类,跳过编译时类型检查.
它本质上实现了一个包装原始类的动画器模式,并动态生成一个新的方法实现.在动态生成的代理方法中,返回类型在写入IL时可以更改,而.NET允许它,因为它不会在运行时检查类型.在编译时,它当然仍然完全有效.这导致了上面相当奇怪的情况,即静态类型实际上与运行时类型不同.
以下是正确的,因为它正在检查实际的运行时类型,在案例中可以解析为布尔值.
updates.GetType().Name == "Boolean"
Run Code Online (Sandbox Code Playgroud)
但是下面的失败是因为它将变量的静态类型与布尔值进行比较,而不是.
updates is bool == false
Run Code Online (Sandbox Code Playgroud)
我建议您不要在Invoke中更改类型.