我有一个奇怪的小错误,它在MvvmLight v4(通过NuGet安装的.NET 4内部版本,v4.0.0.0 / BL0016)下发生。在我的项目中是一个视图模型(继承自ViewModelBase),它表示在画布上绘制的可视元素。该视图模型具有典型的顶部/左侧/宽度/高度属性,每个属性都调用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抱怨我没有从属性设置器中调用RaisePropertyChanged。我已经尝试调试测试(使用Reshaper的测试调试器),但是当我运行调试器时,测试通过了(也许在Resharper中调试单元测试会强制其进入Debug模式,即使已经在Release模式下?)也会发生错误在应用程序本身中。

关于为什么发布模式会破坏代码的任何想法?编译器优化代码的方式是否破坏了ObservableObject的RaisePropertyChanged()方法中StackTrace的使用?请注意,上面的异常未显示正在输入的Width设置器,它直接从CalculateSize方法跳转到该异常。

最佳答案

如果查看MVVM Light代码,您会看到RaisePropertyChanged()使用StackTrace来确定属性的名称。如this post中所述,这在释放模式下可能是个问题。

使用其他RaisePropertyMethod来解决此问题-您可以使用以下方法之一:

RaisePropertyChanged<YourClass>(x => x.Width);


要么

RaisePropertyChanged("Width");


两种方法使用不同的方法来确定已更改的属性的名称(第二种方法仅使用属性名称)。

08-26 19:55