C#核心知识回顾——12.lambda表达式、List排序、协变和逆变

news2024/11/16 13:06:59

1.Lambda表达式

可以将lambad表达式理解为匿名函数的简写
它除了写法不同外,使用上和匿名函数一模一样
都是和委托或者事件配合使用的

//匿名函数
//delegate(参数列表)
//{

//}

//lambda表达式
//(参数列表) =>
//{
      //函数体
//}

//1.无参无返回值
        Action a = () =>
        {
            Debug.Log("Lambda");
        };
        a();
        //2.有参
        Action<int> a2 = (int value) =>
        {
            Debug.Log("参数lambda");
        };
        a2(10);
        //3.参数类型可以省略,参数类型和委托或者事件一致
        Action<int> a3 = (value) =>
        {
            Debug.Log("无类型参数");
        };
        a3(100);
        //4.有返回值
        Func<string, int> a4 = (value) =>
        {
            Debug.Log("返回值");
            return 1;
        };
        a4("a");

闭包:

内层的函数可以引用包含在它外层的函数的变量
即使外层函数的执行已经终止

注意:
该变量提供的值并非变量创建时的值,而是在父函数范围内的最终值。

public class test : MonoBehaviour
{    
    
    private void Start()
    {
        Tes tes = new Tes();
        tes.DoThing();
    }

}

class Tes
{
    public event Action action;

    /// <summary>
    /// 这里就形成了闭包
    /// 当构造函数执行完毕,声明的临时变量value生命周期被改变了
    /// </summary>
    public Tes()
    {
        int value = 10;
        action = () =>
        {
            Debug.Log(value);
        };
        for (int i = 0; i < 5; i++)
        {
            //想要实现for循环存进事件不同的i值,需要在循环内部声明一个临时变量
            //每次存储的index不是同一个index
            int index = i;
            //假如事件注册进5个i变量,但是当使用时,变量的值都是for循环的最终值5,
            action += () =>
            {
                Debug.Log(index);
            };
        }
    }

    public void DoThing()
    {
        action();
    }
}

2.List排序

A.自带排序:

 //list自带排序
        List<int> list = new List<int>();
        list.Add(6);
        list.Add(1);
        list.Add(5);
        list.Add(3);
        list.Add(6);
        list.Add(5);

        list.Sort();

B.自定义排序:

public class test : MonoBehaviour
{

    private void Start()
    {
        List<Items> ite = new List<Items>();
        ite.Add(new Items(2));
        ite.Add(new Items(21));
        ite.Add(new Items(12));
        ite.Add(new Items(52));
        ite.Add(new Items(32));
        ite.Sort();
        for (int i = 0; i < ite.Count; i++)
        {
            Debug.Log(ite[i].id);
        }
    }

}
/// <summary>
/// 继承IComparable接口实现对比
/// </summary>
class Items : IComparable<Items>
{
    public int id;
    public Items(int id) { 
        this.id = id;
    }
    public int CompareTo(Items other)
    {
        //返回值的含义
        //小于0:
        //放在传入对象的前面
        //等于0:
        //保持当前的位置不变
        //大于0:
        //放在传入对象的后面
        //可以简单理解传入对象的位置就是
        //如果你的返回为负数就放在它的左边也就前面
        //如果你返回正数就放在它的右边也就是后面

        if (this.id < other.id)
        { 
            return -1; 
        }
        else
        {
            return 1;
        }
    }
}

C.通过委托函数实现排序

public class test : MonoBehaviour
{

    private void Start()
    {
        List<ShopItem> items = new List<ShopItem>();
        items.Add(new ShopItem(2));
        items.Add(new ShopItem(13));
        items.Add(new ShopItem(24));
        items.Add(new ShopItem(15));

        //1.调用函数
        items.Sort(SortShop);
        //2.匿名函数
        //items.Sort(delegate (ShopItem a, ShopItem b)
        //{
        //    if (a.id > b.id)
        //    {
        //        return 1;
        //    }
        //    else
        //    {
        //        return -1;
        //    }
        //});
        //3.lambda表达式
        //items.Sort((a, b) =>
        //{
        //    return a.id > b.id ? 1 : -1;
        //});

        for(int i = 0; i < items.Count; i++)
        {
            Debug.Log(items[i].id);
        }
    }

    static int SortShop(ShopItem a,ShopItem b)
    {
        //传入的两个对象,为列表中两个对象,进行两两比较
        //用左边的和右边的比较,负数在左边,正数在右边
        if (a.id > b.id)
        {
            return 1;
        }
        else
        {
            return -1;
        }
    }
}

class ShopItem
{
    public int id;
    public ShopItem(int id) 
    {
        this.id = id;
    }
}

 

public class test : MonoBehaviour
{

    private void Start()
    {
        List<ShopItem> items = new List<ShopItem>();
        items.Add(new ShopItem(1,2,3,4));
        items.Add(new ShopItem(4,3,2,1));
        items.Add(new ShopItem(6,7,8,9));
        items.Add(new ShopItem(9,8,7,6));
        items.Add(new ShopItem(3,4,5,6));

        int item = UnityEngine.Random.Range(0, 4);
        items.Sort((a, b) =>
        {
            int index = 0;
            switch (item)
            {
                case 0:
                    index = a.gong > b.gong ? 1 : -1;
                    break;
                case 1:
                    index = a.fang > b.fang ? 1 : -1;
                    break;
                case 2:
                    index = a.xue > b.xue ? 1 : -1;
                    break;
                case 3:
                    index = a.fan > b.fan ? 1 : -1;
                    break;
            }
            return index;
        });

        for (int i = 0; i < items.Count; i++)
        {
            switch (item)
            {
                case 0:
                    Debug.Log(items[i].gong);
                    break;
                case 1:
                    Debug.Log(items[i].fang);
                    break;
                case 2:
                    Debug.Log(items[i].xue);
                    break;
                case 3:
                    Debug.Log(items[i].fan);
                    break;
            }

        }
    }

}

class ShopItem
{
    public int gong;
    public int fang;
    public int xue;
    public int fan;
    public ShopItem(int gong,int fang,int xue,int fan) 
    {
        this.gong = gong;
        this.fang = fang;
        this.xue = xue;
        this.fan = fan;
    }
}

3.协变和逆变

协变:
和谐的变化,自然的变化
因为里氏替换原则 父类可以装子类
比如string变成object
感受是和谐的

逆变:
逆常规的变化,不正常的变化
因为里氏替换原则 父类可以装子类 但是子类不能装父类
所以比如object变成string
感受是不和谐的

协变和逆变是用来修饰泛型的
协变:out
逆变:in
用于在泛型中 修饰 泛型字母的
只有泛型接口和泛型委托能使用

//1.返回值和参数
//用out修饰的泛型只能作为返回值
delegate T Test out<out T>();
//用in修饰的泛型只能作为参数
delegate void Test In<in T>(T t);

public class test : MonoBehaviour
{
    //用out修饰的泛型只能作为返回值
    delegate T TestOut<out T>();
    //用in修饰的泛型只能作为参数
    delegate void TestIn<in T>(T t);
    private void Start()
    {
        //协变 父类总是能被子类替换
        TestOut<Son> os = () =>
        {
            return new Son();
        };
        TestOut<Father> of = os;
        //实际返回的是os里面装的函数 返回的是son
        Father f = of();

        //逆变
        TestIn<Father> iF = (value) =>
        {
        };
        TestIn<Son> iS = iF;
        //实际上 调用的是iF
        iS(new Son());
    }
}
class Father{}
class Son : Father{}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/738326.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Axure高保真原型】冻结固定中继器表格首尾两列

今天和大家分享冻结固定中继器表格首尾两列的原型模板&#xff0c;当我们遇到表格内容较多时&#xff0c;可以用这个模板固定第一列和最后一列操作列。这个模板是用中继器制作的&#xff0c;所以使用也很简单&#xff0c;只需要在中继器里填写对应数据即可&#xff0c;具体效果…

游戏渲染技术:前向渲染 vs 延迟渲染 vs Forward+渲染(二)

GTA5 2 前向渲染 前向渲染是三个光照技术中最简单的&#xff0c;也是游戏图形渲染中最常见的技术。出于这个原因&#xff0c;也是光照计算最昂贵的技术&#xff0c;它不允许在场景中出现大量的动态光源。 大部分使用前向渲染的图形引擎会采用一些技术来模拟场景中大量的光源的…

K8S应用流程安全(镜像安全 配置管理 访问安全)

应用流程安全 1 应用流程安全1.1 镜像安全1.1.1 构建原则1.1.2 Dockerfile实践1.1.3 构建进阶1.1.4 镜像检测1.1.5 仓库升级1.1.6 高可用仓库1.1.7 镜像策略 1.2 配置管理1.2.1 配置基础1.2.2 YAML安全1.2.3 kustomize1.2.4 基础实践1.2.5 功能复用1.2.6 配置定制1.2.7 补丁实践…

python接口自动化(二十七)--html 测试报告——上(详解)

简介 上一篇我们批量执行完用例后&#xff0c;生成的测试报告是文本形式的&#xff0c;不够直观&#xff0c;而且报告一般都是发给leader的&#xff0c;所以最好是直观一目了然&#xff0c;为了更好的展示测试报告&#xff0c;最好是生成 HTML 格式的。unittest 里面是不能生成…

SpringBoot——加载测试专用的配置类

加载测试专用的配置类 之前我们介绍了如何在测试类中加载专用的测试属性&#xff0c;这次我们来看如何在测试类中加载专用的测试类。 创建配置类 首先创建一个配置类&#xff0c;并且创建一个第三方的Bean模拟这是一个要在测试用例中引用的第三方Bean 创建测试用例 创建一个…

第四十三章Java匿名对象

经过前面的学习&#xff0c;我们知道创建对象的标准格式如下&#xff1a; 类名称 对象名 new 类名称(); 每次 new 都相当于开辟了一个新的对象&#xff0c;并开辟了一个新的物理内存空间。如果一个对象只需要使用唯一的一次&#xff0c;就可以使用匿名对象&#xff0c;匿名对…

一起来了解一下Java中的String类吧!!!

简单认识Java中的String类 一、认识String类的重要性 在C语言中已经涉及到字符串了&#xff0c;但是在C语言中要表示字符串只能使用字符数组或者字符指针&#xff0c;可以使用标准库提 供的字符串系列函数完成大部分操作&#xff0c;但是这种将数据和操作数据方法分离开的方式…

vcruntime140_1.dll缺失了要怎么修复?多种方法助你解决丢失问题

我们在使用电脑的时候&#xff0c;其实最经常发生的事情就是蓝屏和dll文件缺失了吧&#xff0c;这也是很多网友最想解决的几个大问题。今天呢&#xff0c;就是有一个网友反映说他的vcruntime140_1.dll缺失了&#xff0c;不知道怎么解决&#xff0c;下面我们就来聊聊vcruntime14…

QT DAY4

做一个闹钟&#xff0c;并播报填写内容 widget.h 文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> #include <QDateTime> #include <QMessageBox> #include<QTextToSpeech> //文本转语音类namespace Ui…

你的流量虚了吗?分析手机流量卡不足量的套路

当今时代&#xff0c;手机流量的使用是每个人每天都在消耗的事情&#xff0c;在有WIFI的情况下还好&#xff0c;大家不需要担心流量用多了还是少了&#xff0c;但是在使用手机流量的时候&#xff0c;就需要注意了&#xff0c;看看是不是会用超什么的&#xff0c;但是现在有一个…

最新总结的软件测试宝典,花2天时间阅完,软件测试面试就过了......

1、测试人员需要何时参加需求分析&#xff1f; 如果条件循序 原则上来说 是越早介入需求分析越好 因为测试人员对需求理解越深刻 对测试工作的开展越有利 可以尽早的确定测试思路 减少与开发人员的交互 减少对需求理解上的偏差 2、软件测试与调试的关系 测试条件已知&#x…

uniapp Android平台各功能模块隐私合规协议

Android平台各功能模块隐私合规协议

STM32 Proteus仿真HCSR04超声波测距报警DS18B20温度采集 -0055

STM32 Proteus仿真HCSR04超声波测距报警DS18B20温度采集 -0055 Proteus仿真小实验&#xff1a; STM32 Proteus仿真HCSR04超声波测距报警DS18B20温度采集 -0055 功能&#xff1a; 硬件组成&#xff1a;STM32F103R6单片机 LCD1602显示器HCSR04超声波测距传感器DS18B20温度传感器…

数学建模常用模型(六):时间序列预测

数学建模常用模型&#xff08;六&#xff09;&#xff1a;时间序列预测 时间序列预测是数学建模中的一个重要领域&#xff0c;用于预测时间序列数据中未来的趋势和模式。时间序列预测可以帮助我们了解数据的演变规律&#xff0c;做出合理的决策和规划。 这是我自己总结的一些代…

FCPX插件-16个手绘卡通素描涂鸦图形文字标题动画 Scribble Sketch Lower Thirds

Scribble Sketch Lower Thirds包含16个手绘卡通素描涂鸦图形文字标题动画模板&#xff0c;一个简约的卡通标题动画&#xff0c;由手绘的文本动画组成&#xff0c;可帮助您轻松改善您影片创意。 这个插件包提供了各种独特的手绘风格的标题动画模板&#xff0c;包括涂鸦笔画、草…

最新FLstudio21.0.3中文版本下载更新及内容介绍

在现在这个数字音乐时代&#xff0c;各种音乐中都或多或少有些电子音乐的影子&#xff0c;或是合成器音色、或是通过数字效果器制作出的变幻莫测的变化效果。而小马丁、Brooks、Eliminate等众多电子音乐巨头便是使用FL Studio来制作音乐的。今天小编就以FL Studio五年的资深用户…

你尚未连接--代理服务器可能有问题,或地址不正确。

这种情况可能是你装了梯子之后&#xff0c;自动开启了代理服务器 解决方法&#xff1a; 1、控制面板->网络和Internet 2、网络和共享中心->internet选项 3、连接->局域网设置 4、把代理服务器的沟沟取消 这样就解决了

多线程与并发编程【线程休眠、线程让步、线程联合、判断线程是否存活】(二)-全面详解(学习总结---从入门到深化)

目录 线程休眠 线程让步 线程联合 Thread类中的其他常用方法 判断线程是否存活 线程的优先级 线程休眠 sleep()方法&#xff1a;可以让正在运行的线程进入阻塞状态&#xff0c;直到休眠时间 满了&#xff0c;进入就绪状态。sleep方法的参数为休眠的毫秒数。 public class…

数据库常见4种范式

数据库范式 1. 数据库范式1.1 第一范式&#xff08;1NF&#xff09;1.2 第二范式&#xff08;2NF&#xff09;1.3 第三范式&#xff08;3NF&#xff09;1.4 巴斯科德范式&#xff08;BCNF&#xff09;1.5 范式的优缺点1.5.1 优点1.5.2 缺点 1. 数据库范式 在关系型数据库中&…

LabVIEW开发汽车安全带张紧测试

LabVIEW开发汽车安全带张紧测试 安全带是车辆乘员安全的主要约束系统&#xff0c;通过遮挡乘员与仪表板或挡风玻璃等接触&#xff0c;显着防止致命或非致命伤害。安全带的实践在三十年内将死亡率降低到相当可观的水平&#xff0c;并且直到今天仍然是许多国家的强制性。 然而&…