如何处理来自可变数量源的事件?

时间:2012-06-23 17:34:33

标签: c#

我有这样的课程(对于可能的错误感到抱歉,我正在这里写。)这个例子简化了类,当然它必须更复杂。

class SP500Index {

    SP500Index(List<OrderBook> stocks) {
        foreach (var stock in stocks) {
            stock.StockUpdated += stockUpdated; // how to handle?
        }
    }

}

所以我有很多来源,我需要从他们处理StockUpdated事件。在处理程序中,我需要知道引发事件的index列表中的stocks库存。怎么做?

更新出于性能原因,我不想要“发件人查找”,而是希望索引。查找不是简单的操作,可能涉及Hashcode计算Equals方法调用等。想象一下SP500索引如何变化......

4 个答案:

答案 0 :(得分:2)

优良作法是使用以下形式的签名:

public delegate void CustomEventHandler(object sender, CustomEventArgs a);

在您的事件处理程序中,您可以使用sender找出引发事件的对象。

如果您没有sender参数,那么我认为没有任何(合理的)方法可以找出引发该事件的对象。

相关

答案 1 :(得分:2)

这不是自动提供的。

但是StockUpdated事件看起来应该是

 void StockUpdated (object sender, MyEventArgs e) 

您可以将sender投射到stock并在原始列表中查找。如果你还需要索引。

 void stockUpdated (object sender, MyEventArgs e) 
 {
    OrderBook stock = (OrderBook) sender;
    ....
 }

答案 2 :(得分:0)

您可以在delegate中定义该事件发送源(基本上是Microsoft的建议指南。拥有object sender,换句话说,就像委托签名的第一个参数一样。

在演示(演员)后,在某些if/else确定真实的对象类型。

答案 3 :(得分:0)

如果您的基准测试表明您在事件发生时需要索引,则可以将索引作为属性添加到OrderBook,并在向列表中添加元素时设置此属性。该值可供事件处理程序使用。

这将假设您将OrderBook个对象保留在一个List中,并且不对此原始列表进行任何重新排列。如果您有多个列表,每个对象只存储在其中一个列表中,那么您可以添加一个引用其存储列表的Owner属性。

例如......

构建List<OrderBook>时:

...
OrderBook book = CreateOrderBook(...);
list.Add(book);
book.ListIndex = list.Count - 1;
// Assign Owner here if that is needed.
...

或者更好的是,使用帮助程序来管理关注索引更新簿记的列表:

public class OrderBookManager
{
    private List<OrderBook> list = new List<OrderBook>();

    public void Add(OrderBook book)
    {
        list.Add(book);
        book.ListIndex = list.Count - 1;
        // Assign Owner here if that is needed.
    }

    // Make this read-only if you want to ensure the manager controls all updates to the list (better design) but use it this way for higher performance.
    public List<OrderBook> List { get { return list; } }
}

更新后的OrderBook

public class OrderBook
{
    ...

    public int ListIndex { get; set; }
}

然后使用此索引的示例事件处理程序:

public void StockUpdated(object sender, MyEventArgs eventArgs)
{
    OrderBook book = (OrderBook) sender;
    //Here use book.ListIndex to access the original list element.
}

您拥有该索引的原因是什么?你需要的一切都应该在对象中。如果您使用它来操作原始列表(例如从列表中删除此项),那么您将遇到重新计算所有先前存储的对象的已保存索引的问题。

如果要维护与其他对象的并行列表,那么您可能应该考虑不同的设计。