我在.NET 4中有一个基于集合的项目。我的意思是,我有一个主集合,称之为“系统”,它由帧组成,每个帧由卡组成,这些是反过来由渠道组成。因此,它看起来像System-> Frame-> Card-> Channel。所有这些都表示为对象,它们之间存在父子关系。从本质上讲,Channel只暴露给Card,Card只暴露给Frame,而Frame只暴露给System。
理想情况下,我希望仅将方法从System类公开给外部世界。但是,Channel,Card和Frame类中会发生重要事件。目前,我处理它们的方式是通过传播。假设在Channel中发生了一个事件。此事件首先在Card中引发,然后在Frame中引发,最后在System中引发。您可以看到这会导致很多代码。但我主要关心的不是代码,而是性能。
你认为这种传播会严重影响我的表现吗?有没有办法让它更有效率?我还有其他选择吗?我的收藏品相对较小。系统是1,帧< 16,卡< 256,频道< 8192.大多数数据都存储在Channel类中,该类只包含原始对象。
EDITS
以下是我在Card中为频道提出的事件所拥有的代码:
protected virtual void OnChannelPropertyChanged(Object sender, PFPropertyChangedEventArgs e)
{
try
{
EventHandler<PFPropertyChangedEventArgs> handler = ChannelPropertyChanged;
TestEventArgs_ChannelPropertyChanged = e;
if (handler != null)
{
handler(sender, e);
}
}
catch (Exception ex)
{
Milltown.MTCore.mtException mtEx = new Milltown.MTCore.mtException((int)PFExceptions.Exception_Hidden_FuctionLevel, ex,
PFCommonVariables.ApplicationPlatform, PFCommonVariables.ApplicationDataSource, "PFCard:OnChannelPropertyChanged");
}
}
当我在Card类中的卡片中添加一个频道时,我打电话给:
channel.ChannelPropertyChanged += this.OnChannelPropertyChanged;
答案 0 :(得分:3)
您可以在System类中执行此操作:
event EventHandler FrameEvent
{
add { this.frame.FrameEvent += value; }
remove { this.frame.FrameEvent -= value; }
}
所以如果客户这样做
system.FrameEvent += Handler;
处理程序实际上附加到Frame类中的Event。
答案 1 :(得分:2)
回答是否影响您的表现的唯一方法是测试它:尝试以某种方式宣传事件,然后再尝试直接附加事件。看哪个更快。
话虽如此,我无法想象当你有一些连续的委托调用而不是一次调用时,你会发现很多 - 如果有的话 - 对性能有可测量的影响。是的,委托调用的速度比实际方法稍慢,因此,在所有条件相同的情况下,添加更多级别的间接比使用常规方法调用具有更大的影响,但这有点过早优化。
如果有人问你如何做你想做的事情,你的方法就是我的建议。除非有问题,否则请继续使用它。
修改强>
在回答你对另一个答案的评论时,我想扩大。 C#事件具有所谓的“属性语法”。如果在类中明确实现,它看起来像这样:
private EventHandler eventDelegate;
public event EventHandler MyEvent
{
add { eventDelegate += value; }
remove { eventDelegate -= value; }
}
(实际上,它使用Delegate.Combine
,但这在这里并不重要)
当您附加到某个活动时,它实际上会调用add
代码,并将该代理传递给value
; remove
也是如此。
当您使用如下的速记事件语法时:
public event EventHandler MyEvent;
它实际上生成的封面内容与我上面发布的代码非常相似。但是,如果您明确说明,则可以在add
和remove
处理程序中执行任何操作。这意味着您可以将目标委托重定向到其他位置。在另一个答案的情况下,它将委托重定向到子对象。
当且仅当以下条件成立时,
object
)如果你有多个孩子,那么技术上可以做到(你可以在add
中循环并附加到所有这些孩子并在remove
中删除所有这些孩子),但是更多难以管理。如果在附加事件后相关对象或对象集合可能发生变化,那么几乎不可能进行协调。
此外,如果您的活动遵循建议的事件做法(将触发对象作为sender
传递),那么因为您将目标直接附加到子事件而不是自己提升,那么您将通过此参数公开对子对象的引用。我不知道这是否与你相关或接受,但它应该被视为。