只有执行修改的代码才能知道它的批量更改何时完成。
我对类似的类所做的是提供SuspendNotifications()
和ResumeNotifications()
方法,它们以明显的方式调用(即在进行大量更改之前调用暂停,完成后调用恢复)。
它们在内部维护一个计数器,该计数器在 SuspendNotifications() 中递增并由 ResumeNotifications() 递减,如果递减结果为零,则发出通知。我这样做是因为有时我会修改一些属性,然后调用另一个修改了更多的方法,它本身会调用挂起/恢复。
(如果 resume 被调用太多次,我会抛出异常。)
如果更改了多个属性,则最终通知不会命名正在更改的属性(因为有多个)。我想您可以累积更改属性的列表并将其作为通知的一部分发出,但这听起来不是很有用。
另请注意,线程安全对您来说可能是也可能不是问题。您可能需要使用锁定和/或Interlocked.Increment()
等。
另一件事是,如果出现异常,您当然最终需要尝试/捕获您的呼叫以暂停/恢复。您可以通过编写实现 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";
}
}
}
}