不同的代表使用

时间:2009-09-01 13:33:28

标签: c# delegates

  

可能重复:
  What is the difference between a delegate and events?

     

可能重复:
  Difference between events and delegates and its respective applications

     

(从this duplicate复制)

当我必须举办活动时,我会这样做

public delegate void LogUserActivity(Guid orderGUID);
public event LogUserActivity ActivityLog;

即使这样也可以

public delegate void LogUserActivity(Guid orderGUID);
public LogUserActivity ActivityLog;

其中两个有什么区别

5 个答案:

答案 0 :(得分:3)

这里有三件事:

  • 声明委托类型
  • 创建委托类型的公共变量
  • 创建委托类型的公共事件

变量只是一个普通变量 - 任何人都可以从中读取,分配给它等。事件只向外界公开订阅/取消订阅功能。您在此处显示的字段式事件实际上具有“默认”订阅/取消订阅行为,存储在具有相同名称的字段中。在声明类中,您可以访问该字段;外面你参加活动。

我有一个article about events和代表,可以更详细地解释。

编辑:要回答评论,您可以使用“无操作”处理程序轻松初始化类似字段的事件:

public event LogUserActivity ActivityLog = delegate{};

答案 1 :(得分:1)

事件是对委托的抽象,就像属性是字段的抽象一样。并且 - 就像属性一样 - 事件允许您对添加/删除处理程序时发生的情况进行精确控制:

public event LogUserActivity ActivityLog
{
    add { ... }
    remove { ... }
}

事实上,您的活动可能根本没有代表支持它,就像财产可能不一定有支持它的字段。

答案 2 :(得分:1)

在大多数情况下,事件和公共代表的不同之处在于使我不能使用公共代表:

<强>事件: obj.ActivityLog = null; //无效

公开代表: obj.ActivityLog = null; //有效

这很重要,因为我只希望订阅者在大多数情况下从列表中添加/删除自己。我不希望其他对象解除其他订阅者的事件。

如果委托不是事件而是更多的回调,我倾向于使用公共方法来执行此操作并使公共委托直接暴露:

obj.RegisterActivityCallback(...)

答案 3 :(得分:0)

在第一种情况下,您可以为ActivityLog事件分配多个侦听器,如:

logger.ActivityLog += new LogUserActivity(Listener1);
logger.ActivityLog += new LogUserActivity(Listener2);

触发事件时将调用两个方法(Listener1和Listener2)。在第二种情况下,您不是创建事件而是创建委托。在这种情况下,您只能分配一个侦听器:

logger.ActivityLog = new LogUserActivity(Listener1);

在这种情况下,您不会触发事件,而是调用委托。事件实际上只是依次调用的一系列代理。

答案 4 :(得分:0)

添加到所有先前的答案,事件是特定类型的委托。委托是一种类型,旨在充当“智能”函数指针,或者换句话说,作为函数指针的智能“包装器”,允许编译器在编译时智能地决定是否为函数( s)您坚持代理与您对委托的使用是一致的(一致性基于函数签名)。

事件是具有特定签名的委托,特别是不返回任何内容的委托(返回void),并且接受两个参数,System.object,以保存对触发事件的任何对象的引用,以及一个实例从System.EventArgs派生的某种类型,用于保存事件需要携带的任何其他数据,从初始化器到处理程序。