集合扩展方法委托的运算事件

Posted zhixin9001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了集合扩展方法委托的运算事件相关的知识,希望对你有一定的参考价值。

?一、集合扩展方法
用于集合操作的扩展方法有Where、Select、Max、Min、Sum、OrderBy、ToList、First、FirstOrDefault、Single、SingleOrDefault等。原来还有Max、Min、Sum这些扩展方法,而且ToList也是扩展的。上一篇有写过MyWhere方法,MySum可这样写:
public static int MySum<T>(this IEnumerable<T> data, Func<T, int> func) {
  int sum = 0;
  foreach (T item in data) {
    sum += func(item);
  }
  return sum;
}

First与FirstOrDefault的区别在于,集合为空或null时,前者会报错,后者则返回空。而如果集合中元素大于一个时,Single和SingleOrDefault会报InvalidOperationException:"Sequence contains more than one element"错误。

二、委托的运算
委托也可以进行加减运算,如有两个符合Action<int>签名的方法F1和F2:
static void F1(int i) {
  Console.WriteLine("this‘s f1:" + i);
}
static void F2(int i) {
  Console.WriteLine("this‘s f2:" + i);
}
用委托a1和a2分别指向F1、F2,然后a3为前两个委托的和:
Action<int> a1 = F1;
Action<int> a2 = F2;
Action<int> a3 = a1 + a2;
执行a3(1)时,会依次运行F1和F2方法,同时它们接受的参数都为1。
执行a3 =a3 - a1后,再次运行a3,则只会执行F2,因为a1被减掉了。如果委托有返回值,相加后的委托执行后的返回值为最后一个方法的返回值。

三、事件
Person类中有事件On12Y,Person的Age每增加12岁,会触发该事件
class Person {
  private int age;
  public int Age {
    get => age;
    set {
      if (value % 12 == 0) {
        //if (On12Y != null) {
        //  On12Y();
        //}
        On12Y?.Invoke();
      }
    }
  }
  public event Action On12Y;
}
//调用,事件触发时调用P1_On12Y
var p1 = new Person();
p1.On12Y += P1_On12Y;
//p1.On12Y = null;
for (var i = 1; i <= 49; i++) {
  p1.Age = i;
}
这是事件的基本使用。
关于事件与委托的关系,可以尝试将上面代码中的public event Action On12Y;修改为public Action On12Y;去掉event修饰符,On12Y就变成了普通的委托,然后在使用时除了可以注册、注销事件外,还可以进行p1.On12Y = null之类的操作。可见事件与委托的区别在于事件在委托的基础上做了限制,只能注册、注销自己。
但事件并不是“特殊的委托”这么简单,事件的完整写法为:
public Action _on12Y;
public event Action On12Y {
  add {
    this._on12Y += value;
  }
  remove {
    this._on12Y -= value;
  }
}
与属性类似,可见事件是对委托的封装。
关于Winform中的事件句柄EventHandler,也是一种委托:public delegate void EventHandler(object sender, EventArgs e);
其签名为事件触发者和事件参数。


学习资料:如鹏网.net提高班http://www.rupeng.com/News/10/4603.shtml






以上是关于集合扩展方法委托的运算事件的主要内容,如果未能解决你的问题,请参考以下文章

创建扩展/自定义控件的方法

C#解惑1——委托&事件(转)

扩展委托Lambdalinq

在值类型上定义的扩展方法不能用于创建委托 - 为啥不呢?

.NET(C#) Nullable(可空类型)通过扩展方法传委托参数调用方法

如何通过 Swift 扩展实现委托方法