只有执行修改的代码才能知道它的这批更改何时完成。
我对类似类所做的是提供SuspendNotifications() 和ResumeNotifications() 方法,它们以显而易见的方式调用(即在进行大量更改之前调用suspend,完成后调用resume)。
它们在内部维护一个计数器,该计数器在 SuspendNotifications() 中递增并在 ResumeNotifications() 中递减,如果递减结果为零,则发出通知。我这样做是因为有时我会修改一些属性,然后调用另一个修改了一些属性的方法,而该方法本身会调用挂起/恢复。
(如果resume调用次数过多,我抛出了异常。)
如果更改了多个属性,则最终通知不会命名正在更改的属性(因为有多个)。我想您可以累积更改属性的列表并将其作为通知的一部分发出,但这听起来不是很有用。
另外请注意,线程安全对您来说可能是也可能不是问题。您可能需要使用锁定和/或Interlocked.Increment() 等。
另一件事是,如果出现异常,您当然最终需要 try/catch 来暂停/恢复调用。您可以通过编写实现 IDisposable 并在其 Dispose 中调用 resume 的包装类来避免这种情况。
代码可能如下所示:
public void DoStuff()
{
try
{
_entity.SuspendNotifications();
setProperties();
}
finally
{
_entity.ResumeNotifications();
}
}
private setProperties()
{
_entity.ID = 123454;
_entity.Name = "Name";
_entity.Description = "Desc";
}
[编辑]
如果你要引入一个接口,比如ISuspendableNotifications,你可以编写一个IDisposable 包装类来简化事情。
下面的例子说明了这个概念;使用NotificationSuspender 简化(实际上删除了)try/catch 逻辑。
请注意,class Entity 当然实际上并没有实现挂起/恢复或提供任何错误处理;这留给读者作为众所周知的练习。 :)
using System;
namespace Demo
{
public interface ISuspendableNotifications
{
void SuspendNotifications();
void ResumeNotifications();
}
public sealed class NotificationSuspender: IDisposable
{
public NotificationSuspender(ISuspendableNotifications suspendableNotifications)
{
_suspendableNotifications = suspendableNotifications;
_suspendableNotifications.SuspendNotifications();
}
public void Dispose()
{
_suspendableNotifications.ResumeNotifications();
}
private readonly ISuspendableNotifications _suspendableNotifications;
}
public sealed class Entity: ISuspendableNotifications
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public void SuspendNotifications() {}
public void ResumeNotifications() {}
}
public static class Program
{
public static void Main(string[] args)
{
Entity entity = new Entity();
using (new NotificationSuspender(entity))
{
entity.Id = 123454;
entity.Name = "Name";
entity.Description = "Desc";
}
}
}
}