我们正在开发一个当前针对.NET Framework 3.5的现有应用程序。在新版本中,应用程序应在.NET 4.5上运行。为了进行测试,我将项目升级为使用.NET Framework 4.5。
首先,似乎一切正常。应用程序(WinForm)按预期运行。当我直接启动可执行文件并且一切似乎都正常工作时没有任何反应。但是,当我从Visual Studio中调试启动应用程序时,会抛出许多NullReferenceExceptions,而不是.NET Framework 3.5的代码。
受影响的代码段如下:
public string ConsistencyContextKey
{
get { return Container.ConsistencyCheckRuleCo.ContextKey; }
}
在异常情况下,属性ConsistencyCheckRuleCo
为空。
对财产的调用是通过反思。在.NET 3.5中,调用来自System.ComponentModel.ReflectPropertyDescriptor.GetValue(object)
。
请参阅CallStack:
在4.5中,此方法已更改,现在转移到方法[System.SecurityUtils.MethodInfoInvoke(MethodInfo, object, object[])]
。
请参阅CallStack:
最后两个属性都通过method.invoke()
调用。
可以找到SecurityUtils.MethodInfoInvoke
的来源here和ReflectPropertyDescriptor.GetValue()
here。
我知道它是4.6.1的来源,但没有任何改变,在4.5中也是如此。
神秘的是,在ReflectPropertyDescriptor
中,还有一个3.5和4.5的Try-Catch。那么为什么Visual Studio会在代码进入我的属性时说有一个用户未处理的异常?
该属性是公共的,不是泛型,类型可见。
答案 0 :(得分:0)
Visual Studio表示用户未处理的异常的原因是“只启用我的代码”设置。调试器无法知道.NET Framework中的方法ReflectPropertyDescriptor.GetValue()
有一个Try-Catch-Block。如果禁用此设置,则警告不再显示。我从这个stackoverflow question得到了提示。
我所做的另一个观察是,如果在3.5中发生异常,则会转发异常。在4.5中,异常将直接抛到它发生的位置。这仅适用于通过反射和方法MethodInfo.Invoke()
调用属性的情况。
我编写了一个测试应用程序,在3.5上,异常已转发给我调用MethodInfo.Invoke()
的方法。在4.5我收到消息“用户未处理的异常”。这意味着在从反射调用处理异常时已经改变了一些东西。