#region Action 和 Func
/*
* 详细资料 https://www.cnblogs.com/kissdodog/p/5674629.html
*
* Action 引用一个void 返回类型的方法,可以传递 16 种不同类型的方法
* Action 没有泛型的话可以调用没有参数的方法
*
*
* Func 允许调用有返回类型的方法,和 Action 类似 也可以传递 16 种不同类型的方法和一个返回类型
* Func委托类型可以调用带返回类型且无参数的方法
* Func
*
*
* 区别:
* Func有返回类型;
* Action只有参数类型,不能传返回类型。所以Action的委托函数都是没有返回值的。
*
*
*/
//class T
//{
// //public static void DH()
// //{
// // for (;;)Console.WriteLine("DH今天,你敲代码了吗?");
// //}
//}
//***********************************
/*
* Func
*
* 代码思路:
* 首先要有一个Main入口啥的,然后就是在 main 里面声明要排序的数组
* 然后后就是要有排序的类(BubbleSorter)了
* 将声明的数组通过 构造的委托类(Employee) 传递到这个方法(Sort)
*
* public static void DH()
* {
* for (;;)Console.WriteLine("DH,今天你思考了吗?");
* }
*/
//class Program
//{
// static void Main()
// {
// Employee[] employees =
// { new Employee("热爱生命 ", 1),
// new Employee("既然选择了远方 ", 2),
// new Employee("我不去想是否能够成功 ", 1),
// new Employee("便只顾风雨兼程 ", 3),
// new Employee("就勇敢地吐露真诚 ", 6),
// new Employee("我不去想能否赢得爱情 ", 4),
// new Employee("我不去想身后会不会袭来寒风冷雨", 7),
// new Employee("一切,都在意料之中 ", 12),
// new Employee("我不去想未来是平坦还是泥泞 ", 10),
// new Employee("既然钟情于玫瑰 ", 5),
// new Employee("留给世界的只能是背影 ", 9),
// new Employee("只要热爱生命 ", 11),
// new Employee("既然目标是地平线 ", 8)
// };
// foreach (var employee in employees)
// {
// Console.WriteLine(employee);
// }
// }
//}
////构造类,用来放置 Main 传递过来的值
//class Employee
//{
// public Employee(string name, decimal salary)
// {
// this.Name = name;
// this.Salary = salary;
// }
// public string Name { get; }
// public decimal Salary { get; private set; }
// public override string ToString() => $"{Name}, {Salary:C}";
// public static bool CompareSalary(Employee e1, Employee e2) =>
// e1.Salary < e2.Salary;
//}
//class BubbleSorter
//{
// static public void Sort (IList sortArray, Func comparison)//sortArray 转递的是值 comparison 就是传递的方法的返回值
// {
// bool swapped = true;
// do
// {
// swapped = false;
// for (int i = 0; i < sortArray.Count - 1; i++)
// {
// if (comparison(sortArray[i + 1], sortArray[i]))
// //将 i+1 和 i 委托到 Employee 里面进行比较 注意,这个 i 代表的是 这个值在数组中的位置
// {
// T temp = sortArray[i]; //将 这个 数 提取出来
// sortArray[i] = sortArray[i + 1];//赋值给 第 i+1 个
// sortArray[i + 1] = temp; //将 第 i 个数的值赋值给第i+1个
// swapped = true;
// }
// }
// } while (swapped);
// }
//}
//*************************************
/*
* 多播委托
*
* Action 这个委托可以被多次显式调用 ,委托里面包含多个方法的委托 就叫多播委托,类似于 Udp 那个多播协议
* 多播委托,可以按顺序调用多个方法。因此 委托的签名就必须返回void 否则 就只能得到最后一个方法的结果
*
*
* https://www.cnblogs.com/bianlan/archive/2013/01/18/2867065.html
*
*
*
* 和其他委托不一样,它可以调用多个方法,而其他委托只能调用一个(类似于 单线程,多线程 的区别,一顿吃一吨,一顿吃多吨)
*
* 支持运算符,就像这个
*
* 用于从委托中删除或添加方法的调用
*
*
* Action operation = K.M;
* operation += K.N;
* Action action3 = action1 + action2;
*
*/
//class T
//{
// static void Main()
// { // Action 封装具有单个参数且不返回值的方法。
// Action a = K.M;//将 a 的值 委托到这个方法
// a += K.N;
// a += K.V;
// // 感觉像一个数组,不断调用数组里面的值
// //这里是和 Fun 地区别 对方法 可以像运算符一样,
// G(a,2);
// G(a,3);
// G(a,5);
// G(a,8);
// //Console.WriteLine(Math.PI);
// }
// public static void G(Action action, double value)
// {
// Console.WriteLine();
// Console.WriteLine($"传递的值 {value}");
// action(value);//通过这个多播委托将值传递
// }
//}
//class K
//{
// public static void M(double value)
// {
// double result = value * 2;
// Console.WriteLine($"乘2, 2 X {value} ={result}");
// //throw new Exception("哎呀,出错了。");//如果某一个环节报了异常,委托会停止 但有时候我并不希望这样 和他的执行顺序有关
// }
// public static void N(double value)
// {
// double result = value * value;
// Console.WriteLine($"{value} 的平方值为{result}");
// }
// public static void V(double value)
// {
// double result = Math.PI;
// Console.WriteLine($"乘圆周率 {value} X π = {result}");
// }
//}
//********************* 利用 delegate 里面的 getinvoactionlist 这个方法 获取委托的链表
//class T
//{
// public static void V()
// {
// Console.WriteLine($"量子叠加态");
// }
// public static void W()
// {
// Console.WriteLine($"量子纠缠");
// throw new Exception();
// }
// public static void M()
// {
// Console.WriteLine("量子自旋");
// }
// static void Main()
// {
// Action a = V;
// a += W;
// a += M;
// //如果某一个环节报了异常,委托会停止 但有时候我并不希望这样
// // delegate 类 定义了一个 GetInvocationlist() 方法 返回一个 delegate 地对象数组,
// //可以使用委托调用委托直接相关的方法 异常不影响
// Delegate[] delegates = a.GetInvocationList();//一个委托数组,其调用列表与此实例的调用列表相匹配。
// foreach (Action d in delegates)
// {
// try
// {
// d();
// }
// catch (Exception)
// {
// Console.WriteLine("波函数坍塌");
// }
// }
// }
//}
//class K
//{
//}
//************************************************************
/*
*/
//class T
//{
// static void Main()
// {
// string mid = ", middle part,";
// //Func anonDel = delegate (string param)//一个委托
// //{
// // param += mid;
// // param += " and this was added to the string.";
// // return param;
// //};
// //lambad 写法
// Func lambad = param =>
// {
// param += mid;
// param += "and this was added to the string.";
// return param;
// };
// Console.WriteLine(lambad("Start of string"));
// }
/*
* 在匿名方法的外面定义一个 字符串变量 mid ,并将变量添加到要传递的参数中,
* 代码返回字符串的值,在调用委托时,把一个字符串作为参数传递,将返回的字符串输出到控制台上
*
*
* 可以用 lambda 表示
*/**
// }
//*****************************************
//delegate void NumberChanger(int n);
// namespace DelegateAppl
// {
// class TestDelegate
// {
// static int num = 10;
// public static void AddNum(int p)
// {
// num += p;
// Console.WriteLine("Named Method: {0}", num);
// }
// public static void MultNum(int q)
// {
// num *= q;
// Console.WriteLine("Named Method: {0}", num);
// }
// static void Main(string[] args)
// {
// // 使用匿名方法创建委托实例
// NumberChanger nc = delegate (int x)
// {
// Console.WriteLine("Anonymous Method: {0}", x);
// };
// // 使用匿名方法调用委托
// nc(10);
// // 使用命名方法实例化委托
// nc = new NumberChanger(AddNum);
// // 使用命名方法调用委托
// nc(5);
// // 使用另一个命名方法实例化委托
// nc = new NumberChanger(MultNum);
// // 使用命名方法调用委托
// nc(2);
// Console.ReadKey();
// }
// }
// }
#endregion