其他分享
首页 > 其他分享> > 笔记【委托•语法篇】委托类型的声明和实例以及Action委托和Func委托

笔记【委托•语法篇】委托类型的声明和实例以及Action委托和Func委托

作者:互联网

B站视频学习笔记 UP:BeaverJoe
【委托•语法篇】委托类型的声明和实例以及Action委托和Func委托
【笔记最后没有做好,有时间再去完善】

03:15 现实世界:什么是委托
08:43 程序世界:什么是委托
13:04 委托为何如此重要
14:45 自定义委托的声明
19:07 C语言函数指针
31:48 创建委托类型的实例与目标方法
38:09 多播委托
39:48 委托的缺点
47:48 Action委托和Func委托
49:32 下期预告
50:30 特别鸣谢

小JOE在外面准备回来,在他们宿舍群发了一条消息 ,说“今天饭很好吃,现在准备回宿舍了”
A舍友看到 我要回来 的消息之后,委托小Joe给他带一份回锅肉盖浇饭。
B舍友看到之后,委托小Joe给他带一份炸鸡。

委托小Joe,去完成 他们各自应该去完成的事情

这个
事件 就是委托字段的包装器,
(事件 看起来像委托类型字段,字段即变量,事件的本质还是event,不是委托字段,小Joe说之后详谈)


切记:一个事件,不管看上去多像一个委托类型的字段,他也不是委托类型的字段,它只是一个委托类型字段的包装器、限制器。限制外界对这个委托字段的访问。
委托类型的字段,通过事件——包装、限制之后,外界只能访问它的 +=、-=操作,只能添加、移除事件处理器。

委托什么,需要的时候就用这个委托,执行相应的事情,委托之外的,概不负责。

我们替舍友呢,去取快递 去带饭 还有呢
就是通过 委托类型的变量 去调用委托类型变量 所存储的各种方法,
(这些方法不需要直接调用)

或者呢 我们可以叫
通过委托类型的变量 去调用那些 封装在委托内部的方法。

C#语言有五大数据类型
而数据类型可以分为:值类型和引用类型

引用类型(Reference Type)包含了:类,接口,委托
值类型(Value Type):结构体,枚举

结构体类型:比如 Struct,Vector2
枚举类型:enum

委托 是一种 类,引用类型的数据结构。

如何[证明]委托是一种类呢,我们可以直接在编译器中 通过typeof操作符来查看一下, 自定义声明的委托[MyDelegate],和C#提供给我们的[Action委托]和[Func委托]

  public delegate void MyDelegate();
        Action action;
        Func<string> func;

        private void Start()
        {
            Console.WriteLine("MyDelegate Is Class Or Not:" + typeof(MyDelegate).IsClass);
            Console.WriteLine("Action Is Class Or Not:" + typeof(action).IsClass);
            Console.WriteLine("Func Is Class Or Not:" + typeof(func).IsClass);

        }

委托的全称是委托类型,他是一种类型。

微软中的 委托的定义: 可以指向 一个或者多个方法,
这里获取的第二个信息:委托类型 创建的实例,可以存储 一个或者多个方法的引用。
直接通过委托的实例 可以【间接调用】 (Invoke或者是Call)调用这些方法。

当然,并不是什么样的方法都可以赋值到委托类型的变量中,
让委托类型的变量来调用。
其中隐含着[类型兼容]的特点。
(这个大概知道了,所以笔记不写了。)

事件的基本 是委托,而Lambda表达式的基础 也是委托,而lambda表达式又是LINQ的基础,
(LINQ: .Net的“Language Integrated Query” 较常用的有:Where/Select
都是以Lambda形式 显示在代码中)。

所以 学好委托,才能理解 事件的本质是 【委托类型字段】的包装器
(只是像字段一样的声明格式,但是不是一个字段,核心是前面的关键字event, )

自定义委托的声明

类可以声明变量
public string PlayerName;

类可以创建实例

比如说 我们声明了一个Player类型的变量:player
之后,通过new关键字 创建Player的一个实例。

当我们拿[引用类型]声明变量后,我们默认它就是一个Null值,
或者 我们可以给它一个Null值,说明这个变量并没有引用任何实例。

或者创建一个委托类型的实例,让这个变量 引用这个实例。

委托是一种类,是引用类型的数据类型。
那么委托和类一样 也可以声明变量、创建委托类型的实例,
实例,也叫做对象,是类经过实例化之后 得到的内存中的实体。

委托虽然是一种类、引用类型,但是它的声明方式和 一般的类 不同。
(主要原因是为了照顾可读性 和C、C++传统)。 反而和一般的方法的声明格式 非常相近。

类的声明的三个要素,
class关键字 类名 {...}花括号内的类体

public delegate void MyDelegate();
delegate关键字,void是MyDelegate中 【目标方法】的返回值类型,
目标方法 是委托可以指向的 这个方法。
或者说 我们委托可以存储的这个方法的引用,存储的这个方法 叫做 目标方法。
叫做目标方法 是因为在编译器中可以观察到target

这个目标方法究竟是什么呢,(委托变量)可以指向什么样的方法呢?
我们之后可以自定义任何一个【返回值为空】【参数列表为空】的方法。

比如:
private void MyMethod()
{
}

为什么委托 它是引用类型,它是一种类,但是它的声明格式,不像类反而像方法呢。
这个问题的答案,简单来说就是
委托的声明 保持了【函数指针】声明类似的格式,
它具有目标方法的【返回值类型】和【参数列表类型】
委托的声明格式 它是仿造C/C++ [函数指针]的声明格式,

函数指针的声明格式是什么样的

int Add(int _a,int _b)
{return _a+_b;
}

通过[函数的名字]来调用这两个函数,
我们称之为 直接调用

什么是间接调用呢,我们会把通过【C++函数指针】来调用这个函数呢,称之为 间接调用
(C#中 就是委托类型变量调用的形式,叫做间接调用)。


#include <iostream>

//(* Calculator) ()        //Calculator 就是这个函数指针类型的名字,可以自定义
// 这种类型的【函数指针】能够指向什么样的函数呢
//我们希望 它所指向的函数 有[两个整数类型的参数] (Add(),Multiply() 两个函数有两个参数)
//(*Calculator)(int _x,int _y)

//并且 能够返回一个 int 整数类型的值  (因为 Add和Multiply 的返回值就是int)
//int (*Calculator)(int _x, int _y);
//这样呢 对[函数指针]的定义\声明,就算基本完成了。

//并且可以用 [typedef关键字] 定义成一种 数据类型, 
//这样我们就拥有了一种 函数指针 数据类型
typedef int (*Calculator)(int _x, int _y);   //这就是函数指针,C语言的声明格式 (我还以为是C++)



int Add(int _a, int _b)
{
    return _a + _b;
}

int Multiply(int _a,int _b)
{
    return _a * _b;
}

int main()
{
    int x = 9;
    int  y = 11;
    printf("Hello World\n");


    //声明函数指针的变量

    //函数指针类型 Calculator  变量名 pointer01
    Calculator  pointer01 = &Add;
    Calculator pointer02 = &Multiply;
    
    //我们现在不再[直接调用]add或者Multiply这两个函数,
    printf("Add Result(pointer01):%d\n", pointer01(x, y));
    printf("Multiply Result (pointer02):%d\n", pointer02(x, y));

    printf("直接调用的 Add Result:%d\n", Add(x, y)); //直接调用
    printf("直接调用的 Multiply Result(pointer02):%d\n", pointer02(x, y));

    std::cout << "Hello World!\n";
    return 0;
}

// C语言:声明一个函数指针;
typedef int (*Calculator)(int _x, int _y);

//C#:委托的声明
public delegate void MyDelagate01(int _a, int _b);
private delegate int MyDelegate02(int _x, int _y);
private delegate double MyDelegate03(double _a);

C#通过委托 这一数据类型,保留了与 函数指针 相对应的这部分内容
(java则毫无保留,通过接口来代替的函数指针)

delegate关键字 对应了 C语言中的*号、指针定义符。

private void Log()
{
Debug.Log("Current Time is:" + System.DateTime.UtcNow);
}

System.DateTime.UtcNow 世界时间、协调世界时间(英国时区)
数据库相关的话,使用这个更好,

System.DetaTime.Now 计算机当地时间

using System;
Action,Func委托在这个名称空间下方。

    private SpriteRenderer sp;

    void Start()
    {
        sp = GetComponent<SpriteRenderer>();   //获取组件
    }

OnEnable方法 会在Awake方法之后,Start方法之前 进行调用,

【笔记最后没有做好,有时间再去完善】

标签:调用,委托,int,类型,Func,Action,函数指针,声明
来源: https://www.cnblogs.com/MinervaZhang/p/16434286.html