SetProperty ref - 对象为空

SetProperty ref - Object is null

我想这只是我忽略的一件非常小的事情,但我不明白为什么这不起作用...

public ObservableCollection<UserDto> Users
{
    get
    {
        return _users;
    }
    set
    {
        SetProperty(ref _users, value);
    }
}

现在当我这样设置Users时,它仍然是null:

pageItem.Object.Users = new ObservableCollection<UserDto>();

如果我像这样使用 "standard" 属性,我可以让它工作:

public ObservableCollection<UserDto> Users { get; set; }

但为什么它不适用于 SetProperty(ref variable, value)

编辑

我正在使用 .NET Framework 4.5.

我也调试了代码。在第一个屏幕截图中,_usersnull,我尝试设置一个 value,其中包含一个 UserDto:

var newUsers = new ObservableCollection<UserDto>();
var user = new UserDto();
newUsers.Add(user);
pageItem.Object.Users = newUsers;  // This steps into the setter

在这一步之后,_users 仍然是 null:

SetProperty 不是内置方法。如果调用此方法后_users字段还是null,则明显是方法实现错误

您可以查看 SetProperty 方法在 Prism 中的实际实现方式,并将此实现与您的实现进行比较:

protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
    if (Equals(storage, value)) return false;

    storage = value;
    RaisePropertyChanged(propertyName);

    return true;
}

https://github.com/PrismLibrary/Prism/blob/master/Source/Prism/Mvvm/BindableBase.cs

出于测试目的,您可以将上述实现粘贴到您的 class 中,为该方法指定另一个名称并调用此方法而不是当前的 SetProperty 方法。

如果您使用的是 Prism 版本的 SetProperty,它应该可以工作。如果不是,你应该证明你的观点:https://whosebug.com/help/mcve

问题是我使用 Mock (http://www.developerhandbook.com/unit-testing/writing-unit-tests-with-nunit-and-moq/) 作为 PageItem:

Mock<GroupCarouselViewPageItem> pageItem = new Mock<GroupCarouselViewPageItem>();

如果我删除 Mock 并只使用 GroupCarouselViewPageItem 作为类型,它会起作用...不是 100% 确定为什么,但它解决了问题。

GroupCarouselViewPageItem i = new GroupCarouselViewPageItem();

感谢您的帮助!

您应该像这样创建 pageItem

Mock<GroupCarouselViewPageItem> pageItem = new Mock<GroupCarouselViewPageItem>() 
{
   CallBase = true;
};

SetPropertyBindableBase class 中 Prism 库中的虚方法,因此如果您创建 GroupCarouselViewPageItem 的 mock,则不会调用任何虚方法。特别是 SetProperty 方法,它改变了 _users 字段的值。 设置 CallBase = true 将导致调用所有虚拟实现。