事件
在C#中,事件是在委托类型变量前加上event关键字,其本质是用来对委托类型的变量进行封装,类似于类的属性对字段的封装。
事件相当于增强了委托的封装性,以保证委托类型的变量在类外部不能被直接调用。这样相当于无论是在类的内部声明public还是protected的委托类型变量,只要用事件event进行封装,其效果都相当于声明了一个private私有的委托类型变量。
————————————————
原文链接:https://blog.csdn.net/Jeffxu_lib/article/details/112008304
委托和事件
主要区别:
1.事件不能再外部使用赋值=符号,只能使用+-委托哪里都能用
2.事件不能在类外部执行,委托哪里都能执行(需要加static、public修饰)
class Program
{
public static Action a = () => { Console.WriteLine("a"); };
}
class test
{
static void test2() { Console.WriteLine("test2"); }
static void Main(string[] args)
{
Program.a();
}
}
3.事件不能作为函数中的临时变量的,委托可以
事件和私有类型的委托变量的区别就在于:私有类型的委托变量在类外部是无法直接访问的,而事件相对于私有类型的委托变量又稍微多了一点点特例,就是事件可以在类外部通过“类名.事件函数名”访问,并能用+-运算符来注册或注销函数,一种阉割版的安全委托。
事件的意义※
1.防止外部随意置空委托
2.防止外部随意调用委托
3.事件相当于对委托进行了一次封装让其更加安全
声明
public event EventHandler<FileListArgs> Progress;
使用方法
using System;
class Program
{
public delegate void mydelegate();
public event Action testevent;
private delegate void mydelegate2();//私有的委托等效事件
static void testevemt() { Console.WriteLine("testEvent");}
static void testfuna()
{
Console.WriteLine("testfuna");
}
static void testfunb()
{
Console.WriteLine("testfunb");
}
static int testfun() { Console.WriteLine("testfun"); return 0; }
static void Main(string[] args)
{
mydelegate2 mye = new mydelegate2(testfuna);
mydelegate2 mye2 = new mydelegate2(testevemt);
mye += mye2;
mye.Invoke();
}
}
错误情况
验证了事件不能在类外调用的特性。
CS0070 事件“Program.testd”只能出现在 += 或 -= 的左边(从类型“Program”中使用时除外)
using System;
class Program
{
public delegate void ClickAction();
public static event ClickAction OnClicked = () => { Console.WriteLine("mydelegate"); };
//匿名+事件,且用系统的Action声明
public static event Action testd = delegate () { Console.WriteLine("testEvent"); };
}
class test
{
static void test2() { Console.WriteLine("test2"); }
static void Main(string[] args)
{
//只可以用+-运算符来注册或注销函数
Program.testd += test2;
Program.OnClicked += test2;
//事件不能在类外调用,报错
// Program.OnClicked += Program.testd;
//Program.testd();
}
}
和lambda表达式
意义:通过lambda表达式(匿名函数),可以在委托中,可以边声明边调用,不需要在而外写类方法,且自带类型推导,可以大大减少代码量。
static void Main(string[] args)
{
//lambda匿名方法(方法)
//无参数匿名函数,声明和定义写在一起
Action a = delegate () { Console.WriteLine(); };
//有参无返回值
Action<int> b = delegate (int a) { Console.WriteLine(a); };
//有参数有返回值
Func<int,int,int> f1 = delegate (int a ,int b) { return a+b; };
//可以更简化,参数变量不用声明类型,用=>写函数内算法
Action<int,int> f2 =(a , b)=> { Console.WriteLine(a + b); };
Func<string,string,string> f3 = (a,b) => { return a+b; };
Console.WriteLine( f1.Invoke(1,3));
}
Unreal种的事件
事件与 组播委托十分相似。虽然任意类均可绑定事件,但只有声明事件的类可以调用事件 的 Broadcast、IsBound 和 Clear 函数。这意味着事件对象可在公共接口中公开,而无需让外部类访问这些敏感度函数。事件使用情况有:在纯抽象类中包含回调、限制外部类调用 Broadcast、IsBound 和 Clear 函数。https://docs.unrealengine.com/4.27/zh-CN/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Delegates/Events/
多播委托和事件
https://www.bilibili.com/video/BV1wp4y1Q76h?spm_id_from=333.999.0.0