using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _8._1委托
{
class Program
{
//1.1声明委托
/*在定义委托时,必须给出它所表示的方法的签名和返回类型等全部细节。
其语法类似于方法的 定义,但 没有方法体,定 义的 前面要加上关键字 delegate。 */
private delegate string GetAString();
static void Main(string[] args)
{
//1.2使用委托
int x = 2;
GetAString firststringmethod = new GetAString(x.ToString);
/*在这段代码中,实 例化了 类型为GetAString的一个委托,并 对它进行初始化,使 它引用整型变量 x的ToString方法。 在 C#中 ,委 托在语法上总是接受一个参数的 构造函 数,这个参数就是委托引用的方法。 这个方法必须匹 配最初定义委托时的签名。*/
/*为了减少输入量,只要需要委托实例,就可以只传送地址的名称。这称为委托推断。只要编译器可以把委托实例解析为特定的类型,这个C#特性就是有效的。 以下代码与上面作用相同:*/
//GetAString firststringmethod = x.ToString;//不要圆括号
Console.WriteLine("String is {0}", firststringmethod.Invoke());//等价于firststringmethod()
int x1 = 40;
GetAString firststringmethod1 = x1.ToString;
Console.WriteLine("String is {0}", firststringmethod1());
Currency balance = new Currency(34, 50);
firststringmethod1 = balance.ToString;
Console.WriteLine("String is {0}", firststringmethod1());
firststringmethod1 = Currency.GetCurrencyUint;
Console.WriteLine("String is {0}", firststringmethod1());
//1.3简单的委托示例
DoubleOp[] Operations =
{
MathOperations.MultiplyByTwo,
MathOperations.Square
};
for (int i = 0; i < Operations.Length; i++)
{
Console.WriteLine("Using operations[{0}]:", i);
ProcessAndDisplayNumber(Operations[i], 2.0);
ProcessAndDisplayNumber(Operations[i], 7.94);
ProcessAndDisplayNumber(Operations[i], 1.414);
Console.WriteLine();
}
//DoubleOp d = MathOperations.Squsre;
//double a=d(2.0);
//Console.WriteLine(a);
//1.4Action<T>和Func<T>委托
/*除了为每个参数和返回类型定义一个新委托类型之外,还可以使用Action<T>和Func<T>委托 。
泛型 Action<T>委 托表示引用一个void返回类型的方法。因为这个委托类存在不同的变体,所以可
以传递至多16种不同的参数类型。没有泛型参数的Action类可调用没有参数的方法。Action<in T>
调用带一个参数的 方法,Action<in T1,in T2>调用带两个参数的方法,Action <in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8>
调用带 8个参数的方法。
Func<T>委托可以以 类似的 方式使 用 。Func<T>允许调用带返回 类型的 方法。 与 Action<T>类似,
Func<T>也定义了 不同的 变体,至 多也可以 传递 16个 参数类犁和一个返回 类型。 Func<out TResult>
委托类型可以调用带返回类型且无参数的方法,Func<in T,out TResult>调 用带一个参数的方法,
Func<in T1,in T2,in T3,in T4,out TResult>调用带 4个参数的方法。*/
Func<double, double>[] Operations1 =
{
MathOperations.MultiplyByTwo,
MathOperations.Square
};
for (int i = 0; i < Operations.Length; i++)
{
Console.WriteLine("Using operations[{0}]:", i);
ProcessAndDisplayNumber(Operations[i], 1.0);
ProcessAndDisplayNumber(Operations[i], 2.0);
ProcessAndDisplayNumber(Operations[i], 3.0);
Console.WriteLine();
}
//1.5BubbleSorter示例
Employee[] employees =
{
new Employee ("hgreuh",2100),
new Employee ("htrhsf",5423),
new Employee ("hsthrt",5398),
new Employee ("shtrj",3532),
new Employee ("htjgkm",8753),
new Employee ("rhehjgf",9356),
new Employee ("yiku",3658),
new Employee ("trghj",3932),
new Employee ("eshfg",1002),
new Employee ("rhfht",2545),
new Employee ("thtrjgf",10000),
new Employee ("tjffgj",12545),
new Employee ("gjyftjd",5637),
new Employee ("yktykf",2988),
new Employee ("hrtjgj",9656),
};
BubbleSorter.Sort<Employee>(employees ,Employee.CompareSalary);
foreach (var employee in employees)
{
Console.WriteLine(employee.ToString ());
}
//1.6多播委托
Action<double> Operations2 = MathOperations1.MultiplyByTwo;
Operations2 += MathOperations1.Square;
ProcessAndDisplayNumber1(Operations2, 4.0);
ProcessAndDisplayNumber1(Operations2, 5.0);
ProcessAndDisplayNumber1(Operations2, 6.0);
Console.WriteLine();
//通过一个委托调用多个方法还可能导 致一个大问 题。多播委托包含一个逐个调用的委托集合。如果通过委托调用的其中一个方法抛出一个异常,整个迭代就会停止。
Action d1 = one;
d1 += two;
Delegate[] delegates = d1.GetInvocationList();//注意Delegate首字母大写(class System.Delegate),GetInvocationList()它返回一个Delegate对象数组。
//try
//{
// d1();
//}
//catch
//{
// Console.WriteLine("Exception caught");
//}
foreach (Action d in delegates)
{
try
{
d();
}
catch
{
Console.WriteLine("Exception caught");
}
}
//1.7匿名方法
string mid = ",middle part,";
Func<string, string> anonDel = delegate(string param)
/*Func<string, string> 委托接受一个字符串 参数,返 回一个字符串。 anonDel是这种委托类型的 变
量。 不是把方法名赋予这个变量,而 是使用一段简单的 代码:它前面是关键字 de1egate,后 面是一个字符串 参数 。
在匿 名方法中 不能使用跳转语句break、 goto或 continue )
跳到该匿名方法的外部,反之亦然:匿 名方法外部的 跳转语旬不能跳到该匿名方法的内 部。
在匿名方法内 部不能 访问 不安全的 代码。 另外,也 不能访问 在匿名方法外部使用的 ref和 out
参数。 但可以 使用在匿名方法外部定义的其他变量。
如果需要用匿名方法多次编写同 一个功能,就 不要使用匿名方法。 在本示例中,除 了 复制代码,
编写一个指定的方法比 较好,因 为该方法只需编写一次,以 后可通过名称引 用它。*/
{
param +=mid ;
param += " and this Was added to the string.";
return param;
};
Console.WriteLine(anonDel("Star of string"));
}
delegate double DoubleOp(double value);
static void ProcessAndDisplayNumber(DoubleOp action, double value)
{
double result = action(value);
Console.WriteLine(
"value is {0},result of operation is {1}", value, result);
}
static void ProcessAndDisplayNumber1(Action<double > action, double value)
{
Console.WriteLine();
Console.WriteLine(
"ProcessAndDisplayNumber1 called with value= {0}", value);
action(value);
}
static void one()
{
Console.WriteLine("one");
throw new Exception("Error in one" );
}
static void two()
{
Console.WriteLine("two");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _8._1委托
{
class MathOperations1
{
public static void MultiplyByTwo(double value)
{
double result= value * 2;
Console.WriteLine(
"Multiplying by two : {0},gives {1}", value, result);
}
public static void Square(double value)
{
double result= value * value;
Console.WriteLine(
"Square {0},giveis {1}", value, result);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _8._1委托
{
class MathOperations
{
public static double MultiplyByTwo(double value)
{
return value * 2;
}
public static double Square(double value)
{
return value * value;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _8._1委托
{
struct Currency
{
public uint Dollars;
public ushort Cents;
public Currency(uint Dollars, ushort Cents)
{
this.Dollars = Dollars;
this.Cents = Cents;
}
public override string ToString()
{
return string.Format("${0}.{1,2:00}", Dollars, Cents);
}
public static implicit operator float(Currency value)
{
return value.Dollars + (value.Cents / 100.0f);
}
public static explicit operator Currency(float value)
{
checked
{
uint dollars = (uint)value;
ushort cents = Convert.ToUInt16((value - dollars) * 100);
return new Currency(dollars, cents);
}
}
public static implicit operator Currency(uint value)
{
return new Currency(value, 0);
}
public static implicit operator uint(Currency value)
{
return value.Dollars;
}
public static string GetCurrencyUint()
{
return "Dollar";
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _8._1委托
{
public class Employee
{
public string Name { get; private set; }
public decimal Salary { get; private set;}
public Employee(string name,decimal salary)
{
Name = name;
Salary = salary;
}
public override string ToString()
{
return string.Format ("{0},{1:c}",Name ,Salary );
}
public static bool CompareSalary(Employee e1,Employee e2)
{
return e1.Salary < e2.Salary;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _8._1委托
{
//1.5BubbleSorter示例
public class BubbleSorter
{
public static void Sort<T>(IList <T > sortArray ,Func<T ,T,bool > comparison)
{
bool swapped = false;
for (int i = 0; i < sortArray.Count; i++)
{
for (int j = 0; j <sortArray.Count-i-1; j++)
{
if (comparison(sortArray[j], sortArray[j + 1]))
{
T temp;
temp=sortArray [j];
sortArray [j] = sortArray[j+1];
sortArray[j+1] = temp;
swapped = true;
}
}
if (!swapped)
{
break;
}
}
}
}
}