原文链接
Unity C# 多态 委托 事件 匿名委托 Lambda表达式 观察者模式 .NET 框架中的委托和事件 | Jason_c
原文写得很好,但是主题格式我不太喜欢,所以我对文章的格式进行了修整,方便自己日后阅读
正文
二、委托
委托:将方法作为参数传递。
using System;
namespace Delegate
{
public delegate void GreetingDelegate(string name);
class People
{
public static void Speak(string name,GreetingDelegate _delegate)
{
_delegate (name);
}
}
class Language
{
public static void EnglishGreeting(string name)
{
Console.WriteLine ("Good Morning,"+name);
}
public static void ChineseGreeting(string name)
{
Console.WriteLine ("早上好,"+name);
}
}
class MainClass
{
public static void Main (string[] args)
{
GreetingDelegate greetingDelegate;
greetingDelegate = Language.EnglishGreeting ;//委托第一次绑定时,须用“=”
People.Speak("Jason", greetingDelegate);
greetingDelegate -= Language.EnglishGreeting;
greetingDelegate += Language.ChineseGreeting ;
People.Speak("杰森", greetingDelegate);
}
}
}
- 运行结果
三、事件
事件:对委托类型的变量的封装;
在类的内部,不管你声明的事件是 public 还是 protected ,它总是 private 的;
在类的外部,注册 += 和注销 -= 的访问限定符与你在 声明事件 时使用的访问符相同。
using System;
namespace Delegate
{
public delegate void GreetingDelegate(string name);
class People
{
public static event GreetingDelegate greetingEvent;
public static void Speak(string name)
{
greetingEvent(name);
}
}
class Language
{
public static void EnglishGreeting(string name)
{
Console.WriteLine ("Good Morning,"+name);
}
public static void ChineseGreeting(string name)
{
Console.WriteLine ("早上好,"+name);
}
}
class MainClass
{
public static void Main (string[] args)
{
People.greetingEvent += Language.EnglishGreeting;
People.Speak ("Jason");
People.greetingEvent -= Language.EnglishGreeting;
People.greetingEvent += Language.ChineseGreeting;
People.Speak ("杰森");
}
}
}
- 运行结果
四、匿名委托
匿名委托:也叫匿名方法,将代码块当做参数传递,因为不需要创建单独的方法,因此 减少了实例化委托所需要的开销 ;
using System;
namespace Delegate
{
public delegate void GreetingDelegate(string name);
class People
{
public static void Speak(string name,GreetingDelegate _delegate)
{
_delegate (name);
}
}
class MainClass
{
public static void Main (string[] args)
{
GreetingDelegate greetingDelegate = delegate(string name) {
Console.WriteLine ("Good Morning,"+name);
};
People.Speak ("Jason",greetingDelegate);
GreetingDelegate greetingDelegate_1 = delegate(string name) {
Console.WriteLine ("早上好,"+name);
};
People.Speak ("杰森",greetingDelegate_1);
}
}
}
在使用匿名方法时候,要 注意
- 不能使用跳转语句跳转到该匿名方法的外部,
- 同样不能用跳转语句从外部跳转到匿名方法内部,
- 匿名方法中不能访问不安全代码(
unsafe), - 也不能访问在匿名方法外部使用的
ref和out参数。
在实际问题中可能遇到的问题要比上面的代码复杂得多,在匿名方法中捕获变量就是难点之一。
- 运行结果:
五、Lambda 表达式
Lambda 表达式:比匿名委托代码更加简洁,运算符 ()=>,
using System;
namespace Delegate
{
public delegate void GreetingDelegate(string name);
class People
{
public static void Speak(string name,GreetingDelegate _delegate)
{
_delegate (name);
}
}
class MainClass
{
public static void Main (string[] args)
{
GreetingDelegate greetingDelegate = (string name) =>
Console.WriteLine ("Good Morning,"+name);
People.Speak ("Jason",greetingDelegate);
GreetingDelegate greetingDelegate_1 = (string name) => {
Console.WriteLine ("早上好," + name);
};
People.Speak ("杰森",greetingDelegate_1);
}
}
}
- 运行结果: