Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在属性设置器中调用方法是否正确?_C#_Wpf - Fatal编程技术网

C# 在属性设置器中调用方法是否正确?

C# 在属性设置器中调用方法是否正确?,c#,wpf,C#,Wpf,在我正在开发的WPF应用程序中,我遇到了以下代码片段: public int SomeInteger { get { return _someInteger; } set { _someInteger= value; OnPropertyChanged("SomeInteger"); SomeIntegerChanged(); } } 如您所见,在属性设置器中调用了一个方法。这种方法正确吗?或者在MVVM模式WPF

在我正在开发的WPF应用程序中,我遇到了以下代码片段:

public int SomeInteger
{
    get { return _someInteger; }
    set
    {
        _someInteger= value;
        OnPropertyChanged("SomeInteger");
        SomeIntegerChanged();
    }
}
如您所见,在属性设置器中调用了一个方法。这种方法正确吗?或者在MVVM模式WPF中有更好的方法吗

正如上面的代码片段是一个示例,实际上属性设置程序可能会在属性更改时加载一个数据表,这可能会很耗时。我尝试使用async和await使应用程序异步,但上述场景会导致问题,因为async和await没有异步属性概念


我还找到了一种将事件绑定到INotifyPropertyChanged的方法,通过检查哪个属性触发事件并调用该方法。但是寻找任何其他替代方法。

在本例中,在Setter中调用方法是可以的。在WPF中为属性更改通知使用INotifyPropertyChanged是正确的方法,将调用添加到Setter是实现它的默认方法

对someinteger的调用已更改;在某种程度上取决于该方法的功能,以及在您已经实现INotifyPropertyChanged的情况下是否需要该方法

将属性用作使用者应该具有尽可能少的副作用,并且通常应该是简单的操作。关于这个话题有一本很好的指南


您还应该避免使用属性名称字符串作为参数,在您的情况下,对OnPropertyChanged的调用应该如下所示:OnPropertyChangednameofSomeInteger

属性设置程序不应启动长时间运行的操作。它应该简单地设置一个支持字段的值,并可能调用一个几乎立即返回的快速同步方法。更多信息请参考@Stephen Cleary's

如果需要在设置SomeInteger时调用异步事件处理程序,例如,可以为PropertyChanged事件连接异步事件处理程序,例如:

this.PropertyChanged += async (s, e) =>
{
    if (e.PropertyName == nameof(SomeInteger))
    {
        await SomeAsyncMethod();
    }
};
这种方法正确吗?或者在MVVM模式WPF中有更好的方法吗

不幸的是,这是所有C语言中普遍接受的MVVM模式。我说不幸是因为这种模式确实遇到了问题。它基于事件——这些事件本身就是有问题的——并且它还导致立即更新,这在许多情况下是不需要的

例如,有时需要两个相互依赖的属性——当用户更改其中一个时,另一个与之相关的属性发生更改——这可能会导致问题,因为无法区分用户更改和代码更改

例如,有时您可能会得到一整棵依赖属性树,所有更改可能需要一段时间才能传播并停止相互干扰

更现代的MVVM方法,如Redux推广的原子更新的单向数据流的单一真相来源,可以避免上述问题。有一个C Redux实现;我不知道它有多容易使用。在我自己的系统中,我构建了自己的失效队列来解决这个问题,直到计算出整个系统的新稳态

我尝试使用async和await使应用程序异步,但上述场景会导致问题,因为async和await没有异步属性概念

对。特别是,您不能异步获取属性。这在MVVM世界中是有意义的;当WPF更新屏幕时,它向您的虚拟机请求一个数据值,那么您的虚拟机就不能说“等一下”,我马上就会得到它。WPF现在需要知道该值,以便可以立即更新屏幕

连接异步事件处理程序是在值更改时启动异步工作的一种方法;这种方法很好。通常,SomeIntegerChanged的存在意味着有一个专门针对该属性的已更改事件,因此通过字符串比较连接到PropertyChanged可能是更难的方法


有关MVVM异步属性的更多信息,请参阅我的。

我要提醒不要过早优化

不要使你的解决方案过于复杂

如果改变是即时的,那么把你喜欢的东西放在二传中是没有问题的

从属属性更改是偶尔需要的,但通常也不是什么大问题

如果你有一个漫长的过程需要开始,那么听起来应该是离散的。您应该在单独的线程上启动该处理,或者将该处理解耦。你可以点燃一堆火,忘掉这条不太优雅的线

您可以使用服务调用、消息队列(如msmq或RabbitMQ或pub-sub)来分离处理。有许多pub-sub方法—一个简单的实现是mvvmlight的messenger或prism的eventaggregator。更复杂的是NServiceBus,甚至是Windows工作流。如果涉及事件,则最好是弱事件。

我真的认为你的l ast段落描述了使事件处理程序异步和使用异步加载方法的正确方法。