C# 委托补充01
程序员文章站
2023-11-18 19:01:40
上一篇文章写了委托的最基本的一些东西,本篇咱们扯扯委托其他的东西。 示例1插件编程 根据对委托的理解,委托可以把一个方法当作参数进行传递,利用这个特性我们可以使用委托,实现插件编程。 这里的Transform方法就是插件方法,它接受一个委托参数。 示例2多播委托 所有的委托都有多播的能力。这就意味着 ......
上一篇文章写了委托的最基本的一些东西,本篇咱们扯扯委托其他的东西。
示例1插件编程
根据对委托的理解,委托可以把一个方法当作参数进行传递,利用这个特性我们可以使用委托,实现插件编程。
public delegate int transformer(int x); class util{ pubilc static void transform(int[] values, transformer t){ for(int i = 0; i < values.length; i++){ values[i] = t?.invke(values[i]); } } } class test{ static void main(){ int[] values = {1,2,3}; util.transform(values, sqare); foreach(int i in values){ console.writeline(i + " "); //1 4 9 } } static int sqare (int x) => x * x; }
这里的transform方法就是插件方法,它接受一个委托参数。
示例2多播委托
所有的委托都有多播的能力。这就意味着一个委托可以引用一个方法,或者引用一个组方法。委托使用 += 和 -=运算符联结多个委托实例。
public class people{} public class student:people{} public delegate void action(); class program { static void say(){ console.writeline("say hi"); } static void write(){ console.writeline("write anything"); } action action = say; action += write;//action = action + write; action(); /* say hi write anything */ }
委托会按照添加的顺序依次触发。如果存在返回值,那么调用者会将最后一个带有非void返回值类型的方法返回值进行返回,其他的返回值将会抛弃。
- 和-= 运算符会从左侧委托操作数中将右侧的委托操作删除。
对于为值为null的委托执行 + 或者+= 操作,等价于为委托指定一个新的值。同样在当委托只有一个目标方法时,执行-=操作等价于为委托指定null值。
由于委托是一个类,所以委托是不可变,每次执行 += 或者-= 实质上等价于从新创建一个新的委托实例,并为它赋值。
具体使用,比如说我们要建一栋大楼,需要很长一段时间,但是公司有要求每建好一层需要给公司汇报一下。
public delegate void progressreporter(int floor); public class edifice{ public static void build(progressreporter p){ for(int i = 0; i < 18; i++){ p(i); system.threading.thread.sleep(1000);//添加点时间 } } } class test{ static void main(){ progressreporter p = writeprogresstoconsole; p += advisetocompany; edifice.build(p); } static void writeprogresstoconsole(int fool) => console.writeline($"{fool}层已建成"); static void advisetocompany(int fool) => console.writeline($"**项目,已经建好{fool}层。"); }
示例3泛型委托
委托类型可以包含泛型类型参数,如:
public delegate t transformer<t> (t t);
通过一个泛型参数,我们可以定义一个通用的transformer,让它对任何类型都有效:
public class util{ public static void transform<t> (t[] values, transformer<t> t){ for(int i = 0; i < values.length; i++){ values[i] = t(values[i]); } } } class test{ static void main(){ int[] values = {1,2,3}; util.transformer(values, square); foreach(int i in values){ console.write(i + " "); //1 4 9 } } static int sqare (int x) => x * x; }
既然委托支持泛型参数,那么就可以定义一些小型的委托类型,它们可以具有任意的返回类型和合理的数目的参数,类如系统定义好的action委托和func委托(out和in标记可变性修饰符,在逆变和协变中有解释)。
delegate void action(); delegate void action<in t> (t arg); delegate void action<in t1, in t2> (t1 arg1, t2 arg2) ……… delegate tresule func(out tresule)(); delegate tresule func<in t, out tresule> (t arg); delegate tresule func<in t1, in t2, out tresule> (t1 arg1, t2 arg2) ………
其中action和func 都可以支持16个参数。
上面的transform重写.
public static void transform<t> (t[] values, func<t, t> transformer){ for(int i = 0; i < values.length; i++){ values[i] = transformer(values[i]); } }
委托还有很多东西,下次聊!
参考自c#7.0核心技术指南