public static void Transform(int[] values, Transformr t) { for (int i = 0; i < values.Length; i++) { values[i] = t(values[i]); } }
static void Main(string[] args) { //委托类型定义了委托实例可以调用的那类方法,具体来说委托类型定义了方法的返回类型和参数 Transformr t = Square; //把方法赋值给委托变量的时候就创建了委托实例 正规写法:Transformr t=new Transformr(Square) //在这里通过委托调用Square方法,使得调用者(Main)和被调用者(Square)解耦了 int answer = t(3); //answer=9;委托实例调用目标方法 正规写法int answer=t.Invoke(3); int[] values = { 1, 2, 3 }; Util.Transform(values, Square); foreach (int i in values) { Console.WriteLine($"{i} "); } //泛型委托 UtilGeneRic.Transform <int>(values, Square); foreach (var i in values) { Console.WriteLine($"{i} "); } //Func就是一种封装好的泛型委托,最后一个参数是输出,返回类型和最后一个参数一致,其他参数是输入,若只有一个参数,那这个参数是输出 //Action无返回类型,所有参数都是输入 //多播委托 /* * 使用+和+=操作符可以合并委托实例 * SomeDeleGate d=SomeMethod1; * d+=SomeMethod2; * 这样子调用d就会调用SomeMethod1和SomeMethod2;而委托的调用顺序和它们的定义顺序一致 * 同理-和-=类似 * 委托的使用+-时操作数可以是null, * SomeDelegate d=null; * d+=SomeMethod1; * 上面两句相当于d=SomeMethod1; * * 注意:委托实质是不可变的,使用+=或者-=时,时机上是创建了新的委托实例,并把它赋给当前的委托变量 * 如果多播委托的返回类型不是void,那么调用者会从最后一个被调用的方法来接收返回值,前面的方法仍然会被调用,但是其返回值就被丢弃了 */ //委托能解决的问题,接口都可以解决 //但是在以下条件之一满足时,更适合使用委托 //1.接口只能定义一个方法 //2.需要多播能力 //3.订阅者需要多次实现接口 //委托类型之间无论怎么都互不相容,只要名字不一样就不一样 //若委托实例拥有相同的目标方法,则委托实例被认为是相等的 //委托的兼容性-参数 //当调用一个方法时,委托的参数可以比方法的参数更加具体(即委托参数是方法的子类依旧可以调用) //例子如下 //delegate void StringAction(string s); //static void ObjectAction(object o) => Console.WriteLine(o); //StringAction sa = new StringAction(ObjectAction); //sa("Hello"); //委托的兼容性-返回类型 //调用方法时,可以得到一个比请求的类型更具体的类型的返回结果 //例子如下 //delegate object ObjectRetriever(); //static string RetrieveString() => "Hello"; //ObjectRetriever o= new ObjectRetriever(RetrieveString); //object result= o() }