我正在尝试编写一个辅助类,给定一个 type 的对象INotifyPropertyChanged
,它可以帮助您验证给定的属性更改确实触发了PropertyChanged
事件。这是我们经常遵循的模式,所以我制作了以下课程来帮助编写单元测试:
public class PropertyChangeHelper<TClass, TProperty> where TClass : class, INotifyPropertyChanged
{
#region Fields
private readonly TClass _model;
private readonly string _propertyName;
private readonly Action<TProperty> _setter;
#endregion Fields
#region Properties
public bool ChangeEventFired { get; private set; }
#endregion Properties
#region Construction
public PropertyChangeHelper(TClass model, Expression<Func<TClass, TProperty>> property)
{
_model = model ?? throw new ArgumentNullException(nameof(model));
if (!(property.Body is PropertyExpression propertyExpression))
throw new ArgumentException("The given expression must be for a property, i.e., with { get; set; }.", nameof(property));
_propertyName = propertyExpression.PropertyInfo.Name;
_setter = targetValue => propertyExpression.PropertyInfo.SetValue(_model, targetValue);
}
~PropertyChangeHelper() => _model.PropertyChanged -= RecordPropertyChange;
#endregion Construction
#region Methods
/// <summary>
/// Updates the property's value to the given target value.
/// </summary>
public void UpdateProperty(TProperty targetValue) => _setter.Invoke(targetValue);
private void RecordPropertyChange(object _, PropertyChangedEventArgs args)
{
if (args.PropertyName == _propertyName)
ChangeEventFired = true;
}
#endregion Methods
}
这个想法是能够传入一个对象(通常是一个 VM)和一个 lambda 表达式来指定有问题的属性,然后告诉它更新值并检查事件是否被触发(或者没有,如果值是相同)。单元测试可能看起来像这样:
[Test]
public void Test()
{
var vm = new VM();
var helper = new PropertyChangeHelper<VM, int>(vm, x => x.SomeIntProperty);
helper.UpdateProperty(5);
Assert.IsTrue(helper.ChangeEventFired);
}
然而,我遇到的问题是我收到Expression
参数错误,指出“Argument type 'lambda expression' is not assignable to parameter type FastExpressionCompiler.LightExpression.Expression<System.Func<VM, int>>
。
我在其他库(例如 Moq)中看到了完全相同的事情,所以我不知道为什么这不起作用。任何人都可以阐明编译器对此不喜欢什么吗?