我遇到了一个奇怪的小错误,在MvvmLight v4 (.NET 4 build, v4.0.0.0/BL0016版本,通过NuGet安装)中出现。在我的项目中,有一个继承自 ViewModelBase 的视图模型表示在画布上绘制的可视元素。该视图模型具有典型的Top/Left/Width/Height属性,每个属性都调用 RaisePropertyChanged 方法。
public double Width
{
get { return _width; }
set
{
if (Math.Abs(_width - value) < DeltaEpsilon)
{
return;
}
_width = value;
RaisePropertyChanged();
}
}
针对不同的事件,视图模型还有一个方法,用于计算可视元素的位置和尺寸,并适当地设置属性:
public void CalculateSize()
{
Width = DoSomeCalculation();
// Calculate other settings...
}
我已经编写了一些单元测试来验证计算的正确性,当我在调试模式下运行时,测试可以正常运行。然而,如果我在发布模式下运行,测试将失败,并出现以下异常:
SetUp : System.InvalidOperationException : This method can only by invoked within a property setter.
at GalaSoft.MvvmLight.ObservableObject.RaisePropertyChanged()
at MyProject.ViewModels.TableViewModel.CalculateSize() in TableViewModel.cs: line 154
在TableViewModel的第154行,Width = DoSomeCalculation()这一行代码处出现了问题。换句话说,当我的方法试图设置属性值时,MvvmLight会抱怨我没有在属性setter内部调用RaisePropertyChanged方法。我尝试使用Reshaper的测试调试器进行调试,但是当我运行调试器时,测试通过了(即使已经处于Release模式下,可能在Resharper中调试单元测试会将其强制转换为Debug模式?)错误也会在应用程序本身中发生。
有什么想法,为什么Release模式会破坏代码?编译器优化代码的方式是否会破坏ObservableObject的RaisePropertyChanged()方法中对StackTrace的使用?请注意,上面的异常并没有显示Width setter被输入,它直接从CalculateSize方法跳到异常。