C#核心知识回顾——11.各数据集合的汇总区分、委托、事件、匿名函数

变量:

无符号
byte正8位  ushort正16位  uint正32位  ulong正64位
有符号
sbyte8位  short16位  int32位  long64位
浮点数
float double decimal
特殊
char bool string

复杂数据容器:

枚举enum
结构体struct
数组(一维、二维、交错) [] [,] [][]

数据集合:

using System.Collections;
ArrayList object数据列表
stack 栈 先进后出
Queue 队列 先进先出
Hashtable 哈希表 键值对

泛型数据集合:

using system.Collections.Generic;
List 列表 泛型列表
Dictionary 字典 泛型哈希表
LinkedList 双向链表
statck 泛型栈
Queue 泛型队列

2.委托

委托是函数(方法)的容器
可以理解为表示函数(方法)的变量类型
用来存储、传递函数(方法)
委托的本质是一个类,用来定义函数(方法)的类型(返回值和参数的类型)
不同的函数(方法)必须对应和各自"格式"一致的委托

关键字:delegate

语法:访问修饰符delegate返回值委托名(参数列表);

可以申明在namespace和class语句块中
更多的写在namespace中
简单记忆委托语法就是函数申明语法前面加一个delegate关键字

声明:

 /// <summary>
    /// 声明了一个可以存储无参无返回值的函数容器
    /// </summary>
    delegate void MyFun();

    //委托声明不能重名(同一语句块)    
    delegate int MyFunc(int a);

使用:

public class test : MonoBehaviour
{    
    /// <summary>
    /// 使用过程
    /// </summary>
    private void Start()
    {
        //无参无返回值委托使用
        MyFun mf = new MyFun(Fun);
        mf.Invoke();
        mf();
        //有参有返回值委托使用
        MyFunc mfc = new MyFunc(Fun2);
        mfc.Invoke(1);
        mfc(2);

        Tet tet = new Tet();
        tet.TestFun(Fun, Fun2);
    }  
    void Fun()
    {
        Debug.Log("fun");
    }
    int Fun2(int a)
    {
        Debug.Log("fun2" + a);
        return a;
    }
}
/// <summary>
/// 声明了一个可以存储无参无返回值的函数容器
/// </summary>
delegate void MyFun();

//委托声明不能重名(同一语句块)    
delegate int MyFunc(int a);

// 委托常用在:
//1.作为类的成员
//2.作为函数的参数
class Tet
{
    public MyFun mf;
    public MyFunc mfc;

    public void TestFun(MyFun mf,MyFunc mfc)
    {
        //可以先处理一些别的逻辑,完事后在执行函数
        this.mf = mf;
        this.mfc = mfc;
    }
}

多函数储存:

public class test : MonoBehaviour
{    
    /// <summary>
    /// 使用过程
    /// </summary>
    private void Start()
    {
        //委托存储多个函数
        //增
        MyFun mf = Fun;
        mf += Fun2;        
        //减(多减不会报错)
        mf -= Fun2;
        //清空容器
        mf = null;
    }  
    void Fun()
    {
        Debug.Log("fun");
    }
    void Fun2()
    {
        Debug.Log("fun2");
    }
}

delegate void MyFun();

系统定义好的委托:

public class test : MonoBehaviour
{    
    /// <summary>
    /// 使用过程
    /// </summary>
    private void Start()
    {
        //无参无返回值
        Action action = Fun;
        action += Fun2;
        action();

        //泛型委托
        Func<string> FuncStr = Func3;

        //可传n参委托
        Action<int, string> action1 = Fun4;
        //可传n参委托。有返回值
        Func<int,int> FuncStr2 = Fun5;
    }
    void Fun(){ Debug.Log("fun"); }
    void Fun2(){ Debug.Log("fun2"); }
    string Func3(){ return ""; }
    void Fun4(int a ,string b) { }
    int  Fun5(int a){ return 0; }
}

delegate void MyFun();

3.事件

事件是什么:
事件是基于委托的存在
事件是委托的安全包裹
让委托的使用更具有安全性
事件 是一种特殊的变量类型

二事件的使用
1.事件是作为 成员变量存在于类中
2.委托怎么用 事件就怎么用

事件相对于委托的区别:
1.不能在类外部 赋值
2.不能再类外部 调用

注意:
它只能作为成员存在于类和接口以及结构体中

public class test : MonoBehaviour
{    
    
    private void Start()
    {
        Tes tes = new Tes();
        tes.myFun = null;
        tes.myFun = TestMyFun;

        //事件不可以在类外部赋值
        //tes.myEvent = null;
        //tes.myEvent = TestMyFun;
        //但是事件可以在外部+=、-=
        tes.myEvent += TestMyFun;
        tes.myEvent -= TestMyFun;

        tes.myFun();
        tes.myFun.Invoke();
        //事件不能在外部调用
        //tes.myEvent();
        //tes.myEvent.Invoke();
        //只能在类内部封装方法去调用
    }
    void TestMyFun() { }
}
class Tes
{
    //委托成员,存储函数
    public Action myFun;
    //事件成员,存储函数
    public event Action myEvent;

    //构造函数
    public Tes(){
        //事件的使用和委托一样
        myFun = TestFun;
        myFun += TestFun;
        myFun -= TestFun;
        myFun();

        myEvent = TestFun;
        myEvent += TestFun;
        myEvent -= TestFun;
        myEvent();
    }

    public void TestFun()
    {
        Debug.Log("122");
    }
}

事件相当于对委托进行了一次封装,更安全。

public class test : MonoBehaviour
{    
    
    private void Start()
    {
        Heater ht = new Heater();
        Alarm alarm = new Alarm();
        Display display = new Display();

        ht.HeaterEvent += alarm.OnAlert;
        ht.HeaterEvent += display.OnDisplay;
        ht.Controll();
    }
}
public class Heater
{
    public delegate void HeaterDelegate(int alert);
    public event HeaterDelegate HeaterEvent;

    private int time;
    public void Controll()
    {
        for (int i = 0; i <= 100; i++)
        {
            time = i;
            if(time > 95)
            {
                if(HeaterEvent != null)
                {
                    HeaterEvent(time);
                }
            }
        }
    }
}

public class Alarm
{
    public void OnAlert(int alert)
    {
        Debug.Log("alarm:已经"+ alert + "度了");
    }
}
public class Display
{
    public void OnDisplay(int alert)
    {
        Debug.Log("Display:烧到" + alert + "度了,可以褪猪毛啦");
    }
}

4.匿名函数

public class test : MonoBehaviour
{    
    
    private void Start()
    {
        //1.无参无返回
        //这样申明匿名函数 只是在申明函数而已 还没有调用
        //真正调用它的时候是这个委托容器啥时候调用就什么时候调用这个匿名函数                
        Action a = delegate ()
        {
            Debug.Log("匿名函数");
        };

        a();
        //2.有参
        Action<int, string> action = delegate (int i, string b)
        {
            Debug.Log("带参匿名");
        };

        action(1,"1");
        //3.有返回值
        Func<int,string> c = delegate (int i)
        {
            return "111";
        };
        //4.一般情况会作为函数参数传递 或者 作为函数返回值
        //参数传递
        Tes tes = new Tes();
        tes.DosThing(100, delegate ()
        {
            Debug.Log("100");
        });
        //返回值
        Action ac2 = tes.GetFun();
        ac2();
        //或者写成:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        tes.GetFun()();
    }

}

class Tes
{
    public Action action1;
    //作为参数传递
    public void DosThing(int a,Action fun)
    {
        Debug.Log(a);
        fun();
    }
    //作为返回值
    public Action GetFun()
    {
        return delegate ()
        {
            Debug.Log("函数内部返回的匿名函数");
        };
    }
}

注意:

因为匿名函数没有名字 所以没有办法指定移除某一个匿名函数

想要移除匿名函数只能清空委托。

所以如果只监听一个函数可以使用匿名函数,监听多个就不要用匿名函数

 

public class test : MonoBehaviour
{    
    
    private void Start()
    {        
        Tes tes = new Tes();
        Func<int,int> fun = tes.GetFun(4);
        fun(2);
    }

}

class Tes
{
    public Func<int,int> GetFun(int m)
    {
        return delegate (int a)
        {
            Debug.Log("函数内部返回的匿名函数"+a*m);
            return a * m;
        };
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值