1.委托
委托是一种引用类型,表示对具有特定参数列表和返回类型的方法的引用
访问权限 delegate 返回值类型 委托名(参数类型)
namespace Program
{
//以下是定义了四个委托
public delegate int Mydelegate1(int a);
public delegate int Mydelegate2(int a, int b);
public delegate void Mydelegate3();
public delegate void Mydelegate4(string str);
class Program
{
static void Main(string[] args)
{
TestData td = new TestData();
td.AddNum(10);
Console.WriteLine(td.num);
}
}
class TestData
{
public int num;
public int AddNum(int a)
{
num += a;
return num;
}
public int MulNum(int a, int b)
{
num *= (a + b);
return num;
}
}
}
1.正常委托形式
class Program
{
static void Main(string[] args)
{
//正常委托形式
Mydelegate m1 = new Mydelegate(td.AddNum);
Console.WriteLine(m1(10));
}
}
2.使用匿名函数形式与lambda表达式
* 匿名函数
* 提供了一种传递代码块作为委托参数的技术,匿名函数是没有方法名,只有函数主体,在匿名函数中不需要指定返回值类型,系统会在函数体中通过return语句自动推断
* 匿名函数只能将方法赋值给委托,通过委托调用该方法
class Program
{
static void Main(string[] args)
{
//匿名函数形式
Mydelegate m11 = new Mydelegate(delegate(int a)
{
return a;
});
Console.WriteLine(m11(120));
//lambda表达式
Mydelegate m12 = new Mydelegate((int a) =>
{
return a;
});
Console.WriteLine(m12(12000));
}
}
3.系统提供的委托形式
* Func:有返回值
* Action:无返回值
* Predicate:返回值为bool
class Program
{
static void Main(string[] args)
{
//采用系统提供的委托 func
//Func<int,int,int> 前两个int为形参类型,最后的int为返回值类型
Func<int, int> f1 = new Func<int, int>(delegate(int a)
{
return a;
});
Console.WriteLine(f1(10));
Func<int, int> f2 = new Func<int, int>((int a) =>
{
return a;
});
Console.WriteLine(f2(20));
//只有一条语句时,在方法体就不需要大括号和return语句,编译器会自动补全
Func<int, int> f3 = new Func<int, int>(a => a);
Console.WriteLine(f2(30));
//采用系统提供的委托 action
//Action<int> int 为形参类型
Action<int> a1 = new Action<int>(delegate(int a)
{
Console.WriteLine(a);
});
a1(50);
Action<int> a2 = new Action<int>((int a) =>
{
Console.WriteLine(a);
});
a2(100);
}
}
4.多播委托
只有相同类型的委托才可以被合并
class Program
{
static void Main(string[] args)
{
Test t = new Test();
t.StartBook();
t.ReadBood();
Mydelegate3 m3 = new Mydelegate3(t.StartBook);
Mydelegate3 m4 = new Mydelegate3(t.ReadBood);
//Mydelegate3 m5 = m3 + m4;//多播委托
//m5();
m4 += m3;
m4();
m4 -= m3;
m4();
}
}
class Test
{
public void StartBook()
{
Console.WriteLine("打开书本");
}
public void ReadBood()
{
Console.WriteLine("开始读书");
}
}
2.事件
事件是一种特殊的委托,委托是事件的基础,本质上来讲事件就是委托。
事件是一种具有特殊签名的委托
如果说委托是对方法的包装,那么事件就是对委托进一步的包装,提升了使用的安全性,事件是安全版的委托。
下面通过一个设计模式---观察者模式来举例
class Program
{
static void Main(string[] args)
{
Cat cat = new Cat();
Mouse mouse = new Mouse();
Person person = new Person();
//注册事件
cat.Catcall += new CatCallEventHandler(mouse.MouseRun);
cat.Catcall += new CatCallEventHandler(person.WakeUp);
cat.OnCatCall();
}
}
//类外创建一个委托
public delegate void CatCallEventHandler();
class Cat
{
//创建事件
public event CatCallEventHandler Catcall;
public void OnCatCall()
{
Console.WriteLine("猫叫了一声");
if (Catcall != null)
{
//Catcall();
Catcall.Invoke();//invoke方法是用于多线程环境中跨线程调用委托,主要作用就是将委托的执行转移到与创建委托线程不同的线程上
}
}
}
class Mouse
{
public void MouseRun()
{
Console.WriteLine("老鼠跑了");
}
}
class Person
{
public void WakeUp()
{
Console.WriteLine("人从梦中惊醒");
}
}