关于Unity C#脚本 【委托】的学习笔记与个人理解...

声明: 代码小白  一点一点啃网课才学明白了一点(算是学明白一点吧...) 然后按照自己听进去的和理解的整理成这篇笔记 笔记里肯定有我理解错和描述错的地方 欢迎各位大佬们指错纠正 非常非常非常希望能向大家学到更多知识!

一、相关概念

1.可以把委托理解成像是class一样的类(委托≈类)。

2.类里面塞【方法】,委托里面塞这些【方法】的【引用】


3.委托有个叫【签名】的属性,要想在里面塞方法的【引用】,需要这个【引用】与【签名】相匹配相一致。

二、如何创建和使用委托

1.声明一个【委托类型

【委托类型】:即我们常说的委托。它像class一样,相当于类。

个人理解:声明委托类型=创建委托。

//声明委托类型/创建一个委托

public delegate void DelegateName(int num);

//加 delegate 才代表声明的是委托
//void代表这个委托返回void值
//DelegateName 是委托名,此委托的名字...
//int num指被此委托【引用】的【方法】,需要 返回值为int类型 才能被此委托调用

对【签名】的个人理解:

2.用这个【委托类型】声明一个【委托变量

【委托变量】:像是类的变量一样。如 { student  s1 = new student(); } ,【s1】就是委托变量 。

3.要对刚创建的【委托变量】进行【初始化】

【初始化】:创建 [委托类型] 的 [对象],把这个 [对象] 赋值给 [委托变量] ,这个过程称为初始化。

【对象】:不能为空,必须包含一个 [引用] ,因为要加 [引用] ,所以 [对象] 要与 [签名] 一致。

个人理解:赋值的值,指引用的方法(值=某个方法),把对象引用的方法塞进委托变量,就是所谓赋值。如果委托变量里面本来就有引用,但是还是把对象赋值给委托变量,那么委托变量会先清空之前所有的引用,然后才会放入对象赋值的那一个引用。

//声明委托变量

DelegateName b1= new DelegateName(MethodName);

//DelegateName是上方声明的委托的名字
//b1是此委托变量的名字
/*MethodName是方法名,就是,下面第三条说的,【对象】因为不能为空,
  所以要塞入一个【引用】,这个MethodName那个被塞入的对象的引用的【方法】的名字...*/
//至此 初始化也已经完成


//第二种声明委托变量写法 效果与上方一样 只是写法不一样
DelegateName b1 = MethodName;


4.使用【对象】,调用方法(即使用委托)

//一个普普通通的类
class Test1
{
    //两个普普通通的方法
    public void Hello(string name)
    {
        Console.WriteLine("Hello!"+name);
    } 

    public void Thank(string name)
    {
        Console.WriteLine("thakn u!"+name);
    } 

    //一个静态方法
    public static void ByeBye(string name)
    {
        Console.WriteLine("byebye!"+name);
    } 
}
class Test2
{
    //声明委托类型(不能写进函数里,但是可以写在类外面也可以写在类里面,这里写在类里面)
    public delegate void DelegateName(string name);     

    static void main(String[] args)
    {
        //创建类对象
        Test1 t1 = new Test1();     
    
        //声明委托变量
        DelegateName d1 = new DelegateName(t1.Hello);
        DelegateName d2 = t1.Thank;

        DelegateName d3 = new DelegateName(Test1.ByeBye);
        //声明对象为静态方法的时候要用类的原名(这里Class1而并非c1)


        //不使用委托,直接引用方法
        t1.Hello("小明");   //运行结果为 Hello!小明

        //使用委托引用方法
        d1("小红");         //运行结果为 Hello!小红

        //组合委托,然后引用组合后的...
        DelegateName d4 = d1 + d2 + d3;
        d4("小丽");

        //使用【委托数组】引用多个方法
        DelegateName[] DelegateArrayName = {d1,d2,d3};
        for(int i = 0 ; i <= DelegateArrayName.Length ; i++ )
        {
            DelegateArrayName[i]("小王");
        }
    
    }
}

运行结果:

三、如何在委托里增删引用

这里我要向d1委托里再加thank方法的引用和d3委托里包含的引用:

DelegateName d1 = t1.Hello;
DelegateName d2 = t1.Thank;
DelegateName d3 = Test1.ByeBye;
d1("小红");

d1 += t1.Thank;
d1 += d3;
d1("小王");

运行结果:

PS:d1原本引用hello方法,之后给d1委托里加其他引用后 又想删掉原本d1的hello引用的话,可以这么写:

DelegateName d1 = t1.Hello;
DelegateName d2 = t1.Thank;
DelegateName d3 = Test1.ByeBye;

DelegateName d4 = d1;
d1 += t1.Thank;
d1 += d3;
d1 -= d4;
d1("小王");

运行结果:

四、匿名方法

个人理解:前面说的,在创建委托变量的时候,为了确保委托变量不能为空,需要跟着引用一个方法。常见为引用已经写好的方法,但是,也可以【在引用的时候,现写一个方法】。

class Test3
{

    public delegate void DelegateName(string name);
    public delegate int DelegateName_1(int num);

    static void Main(String[] args)
    {
        //这里直接在创建委托变量的时候跟着一起创建了方法
        DelegateName d1 = delegate (string name)
        {
                
        };   //注意这里要加上分号
            


        //带返回值的方法也能跟着委托变量进行创建,别忘了写返回值
        DelegateName_1 d1_1 = delegate (int i)
        {
            return i;
        };

        //而且还可以增加其他匿名方法
        d1_1 += delegate(int ii)
        {
            return ii;
        };



        //注:匿名方法声明的变量仅限于匿名方法内,无法在匿名方法外使用,如果使用会报错(如上方name,i,ii)
        //如果是匿名方法外的变量 匿名方法可以使用并改变
        int n1=5;
        d1_1 += delegate(int iii)
        {
            n1=n1+iii
            return iii; 
        };
        d1_1(10);
        Console.WriteLine(n1);  
        //n1的输出结果为上方的初始n1+iii 即5+10 输出结果为15
    

    }
}

五、lambda表达式简化匿名方法

class Test4
{

    public delegate int L_DelegateName(int l_num);

    static void Main(String[] args)
    {
        //普通的委托 引用普通的匿名方法
        L_DelegateName d1 = delegate(int i)
        {
            return i;
        };


        //用lambda表达式 简化匿名方法

        //1、删除delegate、添加lambda运算符=>
        //L_DelegateName d1 =(int i) =>
        //{
        //   return i;
        //};

        //2、此时编译器能从委托签名中获知参数类型,参数类型可省略删除了
        //如果参数带修饰符,参数类型不可省略删除
        //此处示例代码已知参数i输入类型为int,可删除i的参数类型int,但是也可不删,不强求
        //L_DelegateName d1 = (i) =>
        //{
        //   return i;
        //};

        //3、此处参数i因痛失输入类型,遂变为隐式参数,而隐式参数的圆括号可省略
        //如果是是显式参数,即带有输入类型的参数,那么圆括号不可省(如上方的(int i))
        //多个参数的时候 如果没有输入类型,也可以省略括号。但是如果有修饰符了,那么括号和参数类型都不可省略
        //如果委托有返回值,没有参数,那么括号必须留
        //L_DelegateName d1 = i =>
        //{
        //   return i;
        //};

        //4、如果方法里只有一句话那么大括号也可以省略掉,如果该句话是return返回值(此方法中为return i),那么return也可以删掉
        //L_DelegateName d1 = i => i;
            
        //最终简化结果
        L_DelegateName d1 = i => i;

    }
}

六、Action、Func、Predicate委托

Action

class Test5
{
    public static void Num()
    {
        Console.WriteLine("123");
    }

    static void Main(String[] args)
    {

        //Action委托引用的方法必须返回值为void,且没有参数
        //Action委托可以输入至多16个参数
        //Action委托的两种使用方法
        Action a1 = Test5.Num;

        Action<int> a2 = num => Console.WriteLine("123" + num);
        Action<string, int, int> a3 = (name, ID, age) => Console.WriteLine(name + ID + age);
        Action<int, int, int> a4 = (a,b,c) => Console.WriteLine(a+b+c);

        a1();
        a2(123);
        a3("小王", 111, 20);
        a4(10, 20, 30);
    }
}

运行结果:

Func

class Test6
{
    public static int Num()
    {
        return 111;
    }

    static void Main(String[] args)
    {
        //Func委托引用的方法有返回值 但不能有参数
        Func<int> f1 = Test6.Num;

        //当func引用的方法有多个参数的时候 需要在尖括号里加上返回值
        //如下f2委托,尖括号里三个int,前两个表示该func引用的匿名方法有两个int参数,所以后面引用两个参数a,b
        //第三个int表示该func引用的匿名方法的int返回值
        //Func委托可以输入至多16个参数
        Func<int, int, int> f2 = (a, b) => a + b ;

        Console.WriteLine(f1);
        Console.WriteLine(f2(10,20));


    }
}

运行结果:

Predicate

class Test5
{
    //判断是否为5的倍数的方法,如果是5的倍数返回true,不是返回false
    public static bool Num(int num)
    {
        if (num % 5 == 0) 
        {
            return true;
        }
        else 
        {
            return false;
        }
    }
    
    static void Main(String[] args)
    {

        //Predicate定义一组条件,然后判断引用的方法是否满足定义的条件
        //Predicate委托只能输入一个参数 且返回值为bool型
        Predicate<int> p1 = Test5.Num;

        //从1到100遍历一遍,筛查出令p1为true的数
        for (int i = 0; i < 101; i++) 
        {
            if (p1(i) == true) 
            {
                Console.WriteLine(i);
            }
        }
    }
}

运行结果:

关于委托我就学到这里啦,我要继续往下学啦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值