启动线程和任务:需要并行运行某些新的序列,同时运行当前任务,这个序列就称为线程。Thread类的构造函数必须带有一个参数,该参数定义了线程调用的方法。
为了传递方法,将方法的细节封装在一个新的类型的对象中,即委托。委托只是一种特殊类型的对象,其特殊之处在于,我们以前定义的所有对象都包含数据,而委托包含的只是一个或多个方法的地址。
定义委托:
1、定义委托,告诉编译器这种类型的委托表示哪种类型的方法;
2、创建该委托的一个或多个实例。编译器在后台将创建表示该委托的一个类。
private delegate string GetAString();
GetAString firstStringMethod=new GetAString(x.ToString);//x.ToString :将方法的地址赋予给委托变量,如果是x.ToString()就是调用方法,不能赋予给委托
Console.WriteLine("String is {0}",firstStringMethod());
Console.WriteLine("String is {0}",x.ToString());
firtStringMehod():使用委托显示字符串,后面的圆括号中包含调用该委托中的方法时使用的任何等效参数。上面两个显示方法效果相同。
给委托实例提供圆括号与调用委托类的Invoke()方法完全相同。
firstStringMethod()等价于
firstStringMethod.Invoke()
为了减少输入量,只要需要委托实例,就可以只传送地址的名称,称为委托推断。
给定委托的实例可以引用任何类型的任何对象上的实例方法或静态方法--只要方法的签名匹配于委托的签名即可。
使用委托的一个小例子:
在类中定义了方法:
namespace Ado_net_demo1
{
class ClassOperater
{
public static double MultiplyByTwo(double value)
{
return value* 2;
}
public static double Square(double value)
{
return value * value;
}
}
}
应用:
namespace Ado_net_demo1
{
class Program
{
delegate double DoubleOperate(double v);
static void Main(string[] args)
{
DoubleOperate[] operate ={
ClassOperater.MultiplyByTwo,
ClassOperater.Square
};
for (int i = 0; i < operate.Length;i++ )
{
Console.WriteLine(i.ToString());
ProcessAndDisplayNumber(operate[i], 2.0);
ProcessAndDisplayNumber(operate[i], 7.94);
ProcessAndDisplayNumber(operate[i], 1.414);
}
Console.ReadKey();
}
static void ProcessAndDisplayNumber(DoubleOperate operate,double value)
{
double result = operate(value);
Console.WriteLine("value is {0},result is {1}", value, result);
}
}
}
利用Func<double,double>:前面是参数0-16个,后面是输入参数,只能有一个
namespace Ado_net_demo1
{
class Program
{
delegate double DoubleOperate(double v);
static void Main(string[] args)
{
Func<double, double>[] funs = {
ClassOperater.MultiplyByTwo,
ClassOperater.Square
};
for (int i = 0; i < funs.Length;i++ )
{
Console.WriteLine(i.ToString());
ProcessAndDisplayNumber(funs[i], 2.0);
ProcessAndDisplayNumber(funs[i], 7.94);
ProcessAndDisplayNumber(funs[i], 1.414);
}
Console.ReadKey();
}
static void ProcessAndDisplayNumber(Func<double,double> funs,double value)
{
double result = funs(value);
Console.WriteLine("value is {0},result is {1}", value, result);
}
}
}
看下委托的真正用途:
我们使用委托对所有类型的数组进行冒泡排序:
给自定义的类或数组排序,在委托中传递一个封装的方法。
定义了employee类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ado_net_demo1
{
class Employee
{
//类的构造函数
public Employee(string name,decimal salary)
{
this.Name = name;
this.Salary = salary;
}
public string Name {get;private set; }//最后不用分号
public decimal Salary { get;private set;}
public override string ToString()
{
return string.Format("{0},{1:C}",Name,Salary); //decimal的输出格式
}
public static bool CompareSalary(Employee e1,Employee e2)//这里的方法匹配Func<T,T,bool>
{
return e1.Salary<e2.Salary;
}
}
}
定义了委托方法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ado_net_demo1
{
class ClassOperater
{
public static void Sort<T>(IList<T> sortArray,Func<T,T,bool> comparsion)//第一个参数是对象数组
{
bool swap = true;
do
{
swap = false;
for (int i = 0; i < sortArray.Count-1; i++)
{
if (comparsion(sortArray[i+1], sortArray[i]))
{
T temp = sortArray[i];
sortArray[i] = sortArray[i + 1];
sortArray[i + 1] = temp;
swap = true;
}
}
} while (swap);
}
}
}
使用其方法进行排序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
namespace Ado_net_demo1
{
class Program
{
static void Main()
{
Employee[] employees =
{
new Employee("hello",1234),
new Employee("vivi",20000),
new Employee("wel",23254),
new Employee("kime",4543),
new Employee("padn",39485)
};
ClassOperater.Sort(employees, Employee.CompareSalary);
foreach (var employ in employees)
{
Console.WriteLine(employ);
}
Console.ReadKey();
}
}
}