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.
我也调试了代码。在第一个屏幕截图中,_users
是 null
,我尝试设置一个 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;
};
SetProperty
是 BindableBase
class 中 Prism 库中的虚方法,因此如果您创建 GroupCarouselViewPageItem
的 mock,则不会调用任何虚方法。特别是 SetProperty
方法,它改变了 _users
字段的值。
设置 CallBase = true
将导致调用所有虚拟实现。
我想这只是我忽略的一件非常小的事情,但我不明白为什么这不起作用...
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.
我也调试了代码。在第一个屏幕截图中,_users
是 null
,我尝试设置一个 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;
};
SetProperty
是 BindableBase
class 中 Prism 库中的虚方法,因此如果您创建 GroupCarouselViewPageItem
的 mock,则不会调用任何虚方法。特别是 SetProperty
方法,它改变了 _users
字段的值。
设置 CallBase = true
将导致调用所有虚拟实现。