一、委托的定义
委托是持有一个或多个方法的对象。但委托与典型的对象不同,委托可以执行,这时委托会执行它所持有的方法。
委托使用的时机:当程序运行时,不能确定具体调用那个方法时。
(在运行时要求,动态选择使用的方法)
二、委托的使用
1、声明一个委托类型。委托声明看上去和方法声明相似,只是没有实现块
2、使用该委托类型声明一个委托变量
3、创建一个委托类型的对象,并把它赋值给委托变量
4、你可以选择为委托对象添加其他方法
5、在代码中你可以像调用方法一样调用委托
class Program
{
static void Main(string[] args)
{
Item i1 = new Item() { Price = 500, Type = "大武器类", Grade = 11 };
Item i2 = new Item() { Price =2000, Type = "超大食物类", Grade = 6 };
Item i3 = new Item() { Price = 700, Type = "装备类", Grade = 7 };
Back b = new Back();
b.Add(i1);
b.Add(i2);
b.Add(i3);
//b.Sort(CompareByGrade);
//b.Sort(CompareByPrice);
b.Sort(CompareByType);
b.Print();
Console.ReadLine();
}
public static int CompareByPrice(Item x, Item y)
{
return x.Price - y.Price;
}
public static int CompareByGrade(Item x, Item y)
{
return x.Grade - y.Grade;
}
public static int CompareByType(Item x, Item y)
{
return y.Type.CompareTo(x.Type);//CompareTo用于比较字符串
}
}
class Item
{
public int Price;
public string Type;
public int Grade;
public override string ToString()
{
return string.Format("id={0},name={1},Grade={2}",Price,Type,Grade);
}
}
class Back
{
private Item[] back = new Item[100];
private int n = 0;
public void Add(Item item)
{
if (n >= back.Length)
throw new InvalidOperationException("数组已满");
back[n] = item;
n++;
}
public void Print()
{
for(int i=0;i<n;i++)
{
Console.WriteLine(back[i]);
}
}
public void Sort(CompareDelegate cd)
{
for (int i = 0; i < n-1 ; i++)
{
for (int j = 0; j < n - i-1; j++)
{
//if (back[j].Price > back[j+1].Price)
if(cd(back[j], back[j+1])>0)
{
Item temp = back[j];
back[j] = back[j + 1];
back[j + 1] = temp;
}
}
}
}
//如果返回值>0,表示i1在i2的后面
public delegate int CompareDelegate(Item i1, Item i2);
}
委托的定义与使用
public delegate void MyDelegate();
class Program
{
static void Main(string[] args)
{
MyDelegate md = new MyDelegate(print); //赋值委托1
md();//执行方法
Test tt = new Test();//赋值委托2
MyDelegate md2 = tt.tprint;
md2();//执行方法
MyDelegate md3 = tt.tprint;//当一个类中有多个类时,可以使用+=添加在类中的其他方法
md3 += tt.t2print;
md3-=tt.t2print;
md3=tt.tprint+t2print;//组合委托
md3();
Console.ReadLine();
}
static void print()
{
Console.WriteLine("内部方法");
}
}
class Test
{
public void tprint()
{
Console.WriteLine("这是一个尝试");
}
public void t2print()
{
Console.WriteLine("这是第二个尝试");
}
}
当委托调用带返回值的委托时
1、调用列表中最后一个方法返回的就是委托调用返回的值
2、调用列表中所有其他方法的返回值都会被忽略
三、Lambda表达式:更简单的使用代理
1、编译器类型推断
2、语法格式:{参数列表}=>{方法体}
例如:
b.Sort(x,y)=>{return x.Price-y.Price}
b.Sort(x,y)=>{return x.Type.CompareTo(y.Type)}
四、C#内嵌的委托类型
System.Action<> 是一个泛型委托(delegate)类型,用于表示没有返回值的方法或操作。
System.Func<>用于表示有返回值的函数。为了方便适应不同参数个数
使用delegate定义没有返回值的委托
使用Action<T1, T2>委托,则不需要显式定义委托:
使用泛型Func<T1, T2, TResult>委托, 则不需要显式定义委托: