日期:2014-05-18  浏览次数:20924 次

关于VC中事件运算符+=(add方法)的操作问题
测试代码如下:
(1)
public delegate int Del(int i);
public ref struct C {
  int i;
  event Del^ MyEvent;
  //Del^ MyEvent;

  void FireEvent() {
  i = MyEvent(i);
  }
};

ref struct EventReceiver {
  int OnMyClick(int i) { return ++i; }
};
void funcfor_event()
{
  C c;
  c.i = 687;

  c.FireEvent();
  Console::WriteLine(c.i);
  c.i = 688;
  Console::WriteLine(c.i);

  EventReceiver^ MyEventReceiver1 = gcnew EventReceiver();
EventReceiver^ MyEventReceiver2 = gcnew EventReceiver();
EventReceiver^ MyEventReceiver3 = gcnew EventReceiver();
  c.MyEvent += gcnew Del(MyEventReceiver1, &EventReceiver::OnMyClick);
c.MyEvent += gcnew Del(MyEventReceiver2, &EventReceiver::OnMyClick);
c.MyEvent += gcnew Del(MyEventReceiver3, &EventReceiver::OnMyClick);
  c.FireEvent();
  //c.FireEvent();
  Console::WriteLine(c.i);
}
我的理解是如果c.MyEvent在委托列表中添加了三个事件,那么这三个事件都应该执行,如果是按照顺序执行则i最后的值应该增加3,但是现在i的值确是689,请问是为什么?

(2)
public delegate int Del(int i);
public ref struct C {
  int i;
  event Del^ MyEvent;
  //Del^ MyEvent;

  void FireEvent() {
  i = MyEvent(i);
  }
};

ref struct EventReceiver {
  int OnMyClick(int i) { return ++i; }
};

int f(int i)
{
  cout<<"ssssssss"<<i<<endl;
  return 1;
}

int f1(int i)
{
  cout<<"zzzzzzzzz"<<i<<endl;
  return 1;
}
void funcfor_event()
{
  C c;
  c.i = 687;

  c.FireEvent();
  Console::WriteLine(c.i);
  c.i = 688;
  Console::WriteLine(c.i);

  EventReceiver^ MyEventReceiver = gcnew EventReceiver();
  c.MyEvent += gcnew Del(MyEventReceiver, &EventReceiver::OnMyClick);
  c.MyEvent += gcnew Del(f);
  c.MyEvent += gcnew Del(MyEventReceiver, &EventReceiver::OnMyClick);
  c.MyEvent += gcnew Del(f1);;
  c.FireEvent();
  //c.FireEvent();
  Console::WriteLine(c.i);
}
如(2)这部分代码,在c.MyEvent委托列表中增加了f和f1两个事件,执行的结果是:
0
688
ssssssss688
zzzzzzzzz688
1
请按任意键继续. . .
不明白为什么顺序上有区别,而且zzzzzzzzz688为什么对i没有加1?

------解决方案--------------------
1.写这么乱的代码纯粹是折磨自己;
2.问题1三个事件的输入参数都是688,所以输出都是689,你可以在事件响应函数里跟踪下是否正确。没有累加性,int是值对象的,你可以改用ref看看。
3.问题三你return的是1,不知道如何能加1?delegate维护一个链表,所有是有顺序的。
------解决方案--------------------
你这里几个问题其实是一个问题,理解了都通,不理解都想不通。
这里添加的多个事件的确都执行了,而且肯定是按照添加的顺序执行的,但是你用成员变量i接收返回值仅一次,接收的是最后一次执行的返回值,如果添加了4个事件,且每个事件的返回值都不同,你会发现,i得到的将是最后一次执行的那个事件的返回值,前面几个事件的返回值被丢弃了。因此事件中不要用返回值来处理最终结果,那样是不准确的,一般是通过参数传递一个自定义的EvengArgs对象,修改其自定义属性来实现累加值的变化效果。