unity的语言问题记录(委托相关)

news2024/9/21 18:38:32

NGUI跟随鼠标实例位置

  // 获取鼠标位置
        Vector3 mousePos = Input.mousePosition;

        // 将屏幕坐标转换为NGUI的世界坐标
        Vector3 worldPos = UICamera.mainCamera.ScreenToWorldPoint(mousePos);
        worldPos.z = 0; // 确保图片在UI层

        // 设置图片位置
        instantiatedImage.transform.position = worldPos;

// 将屏幕坐标转换为NGUI的世界坐标 Vector3 worldPos = UICamera.mainCamera.ScreenToWorldPoint(mousePos); worldPos.z = 0; 

List

在处理List集合时,foreach循环和for循环配合list[i]的使用确实在大多数情况下是功能等效的,但它们在某些方面还是有一些区别和适用场景:

1. foreach循环

foreach (var item in myList)
{
    Console.WriteLine(item);
}
  • 可读性foreach循环通常更简洁和易读,特别适合需要遍历整个集合而不修改集合的场景。
  • 避免索引错误:由于不使用索引,foreach循环减少了由于错误使用索引而导致的异常。
  • 更安全foreach不允许在遍历过程中修改集合(如添加或删除元素),因此更安全,但这也意味着它不适用于需要修改集合的场景。

2. for循环

for (int i = 0; i < myList.Count; i++)
{
    Console.WriteLine(myList[i]);
}
  • 灵活性for循环允许更灵活的操作。你可以通过索引访问和修改集合中的元素,还可以轻松地跳过或重复某些元素。
  • 部分遍历:你可以通过修改索引变量的值,轻松实现部分遍历,或者从特定位置开始遍历集合。
  • 支持反向遍历:通过调整索引变量的初始值和步长,for循环可以轻松实现从集合末尾向前遍历。
  • 修改集合:在for循环中,可以安全地对集合进行添加、删除或替换操作,只需小心管理索引。

3. 性能

  • 对于List这种基于数组的数据结构来说,foreachfor在性能上几乎没有差别,因为foreach在内部使用了类似索引的方式来遍历集合。
  • 然而,在某些情况下,for循环可能略微优于foreach,尤其是当你频繁访问元素索引时,因为for循环可以避免foreach循环在每次迭代中创建的额外迭代器对象。

4. 适用场景

  • foreach:适用于遍历整个集合、不需要知道索引或者不打算修改集合的场景。
  • for:适用于需要部分遍历、按特定顺序遍历、反向遍历,或者需要修改集合内容的场景。

总结:

  • 如果你只是遍历集合并读取元素,foreachfor几乎没有区别,foreach更简洁。
  • 如果需要修改集合内容、实现复杂的遍历逻辑,或者部分遍历,for循环可能会更适合。

元组解构赋值

元组解构赋值,这种语法允许在一行代码中交换两个变量的值。这种语法在C# 7.0及以上的版本中引入,并且可以用于元组的解构和多变量的同时赋值。

例如,这段代码:

(keys[index1], keys[index2]) = (keys[index2], keys[index1]);

在这里,(keys[index1], keys[index2]) 是一个元组,包含两个元素。右边的 (keys[index2], keys[index1]) 也是一个元组。C# 的解构赋值语法允许你直接将右边元组的值分配给左边的对应位置的变量,这样你可以很方便地交换两个变量的值。

为什么用元组解构赋值?

  • 简洁:不需要像传统方法那样使用临时变量来交换两个值。
  • 直观:在同一行代码中直接交换多个变量的值,代码更加清晰。

传统的交换方式

在引入这个语法之前,交换两个变量通常是这样实现的:

var temp = keys[index1];
keys[index1] = keys[index2];
keys[index2] = temp;

元组解构赋值提供了一种更加简洁的方式来实现相同的操作。

这个语法虽然在C#中相对较新,但它在其他编程语言如Python中早已广泛使用。

C#中的这种新特性,同样有C# 7.0及以后版本引入的其他功能,例如本地函数、模式匹配等。

var

在C#中,var是一个隐式类型变量声明的关键字,它允许编译器根据右侧赋值的类型自动推断变量的类型。当你使用var来声明一个变量时,编译器会根据赋值的表达式确定该变量的实际类型。

举个例子,如果你将一个List<int>赋值给一个var变量,编译器会自动推断出该变量的类型是List<int>

var myList = new List<int> { 1, 2, 3 };

在这个例子中:

  • var myList 声明了一个变量myList
  • 右边的赋值是 new List<int> { 1, 2, 3 },这是一个 List<int> 类型的对象。
  • 因此,编译器会将 myList 的类型推断为 List<int>

这意味着 myList 是一个 List<int> 类型的变量,并且你可以像操作普通 List<int> 变量一样操作它。

关键点:

  • var 并不是一个动态类型编译时它的类型就已经确定了。在编译后,var 就会被替换为实际的类型。
  • var 只能用于局部变量声明,并且必须在声明时进行初始化,编译器才能推断类型。

因此,var 可以存储一个 List,因为编译器能够从赋值的表达式中推断出 List 的类型。

除了谓词还可以在什么情况下使用

在 C# 中,除了谓词(如 AnyWhere 等 LINQ 方法)之外,lambda 表达式 可以用于多种场景。以下是一些常见的应用场景:

1. 委托

Lambda 表达式 可以用来简化委托的使用。委托是一种引用方法的类型,在 C# 中可以使用 lambda 表达式 来创建匿名方法并将其赋值给委托。

示例:
Func<int, int, int> add = (x, y) => x + y;
int result = add(3, 4); // result 为 7

 在这个例子中,add为声明的func委托名,=>后的部分直接等价于{return x+y;}

至于谓词在List.Any中的使用,因为谓词可以说是返回bool的一种委托,所以有异曲同工之妙

2. 事件处理

在事件处理程序中,lambda 表达式 可以用作处理事件的匿名方法。

示例:
button.Click += (sender, e) => 
{
    Console.WriteLine("Button clicked!");
};

这个例子中,当按钮被点击时,lambda 表达式 定义的匿名方法将被调用。

3. 线程与任务

在多线程编程中,可以使用 lambda 表达式 来简化线程或任务的定义。

示例:
Task.Run(() => 
{
    // 任务代码
    Console.WriteLine("Task running");
});

4. LINQ 查询表达式

除了常见的 AnyWhere 方法外,lambda 表达式 还可以用于 SelectOrderByGroupBy 等 LINQ 方法。

示例:
var names = items.Select(item => item.name).ToList();

在这个例子中,lambda 表达式 用于从 items 列表中选择 name 属性,并生成一个新列表。

5. 简化条件逻辑

你可以在任何需要传递函数或执行代码块的地方使用 lambda 表达式,比如简化条件逻辑。

示例:
Action action = () => Console.WriteLine("Hello, World!");
action();

这个例子中,Action 是一个不接受参数且不返回值的委托类型。lambda 表达式 定义了 action 的行为,并在后续调用时执行。

6. 自定义扩展方法

你可以使用 lambda 表达式 在自定义扩展方法中作为参数传递,来灵活地定义行为。

示例:
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach (T element in source)
    {
        action(element);
    }
}

// 使用扩展方法
items.ForEach(item => Console.WriteLine(item.name));

 委托中的闭包提供了强大的功能,使得你能够创建灵活的、具有状态的匿名函数

info => info.id == 1001

为什么要写这么奇怪的语法?

这是因为 lambda 表达式 的语法和功能所决定的。Lambda 表达式 是 C# 中用于简化匿名方法的一种语法,它可以直接在代码中定义一个小型函数,并将其传递给 LINQ 方法(如 AnyFirstOrDefaultWhere 等)。这些方法依赖于 lambda 表达式 来描述要对集合中的每个元素执行的操作。

为什么可以把 item 当参数来写?

Lambda 表达式 的作用就是为每个元素定义一个临时函数。这个临时函数接受集合中的一个元素作为输入参数,并对其进行操作。因此,当你写 item => item.id == 1001 时,item 就是这个临时函数的参数,表示集合中的每一个单独的元素。

为什么知道它就是个体?

这是 LINQ 方法的设计原理决定的。比如,Any 方法定义为接受一个返回布尔值的函数(也就是 Predicate,它会自动将集合中的每个元素依次传递给这个函数,并检查这个元素是否满足给定的条件。因此,在 Any 方法的上下文中,lambda 表达式 的参数必然就是集合的一个元素。

为什么要用这种语法?

Lambda 表达式 是为了简化代码而设计的。相比传统的匿名方法,它更加简洁,且与 LINQ 查询表达式紧密结合,使得对集合进行查询、过滤、投影等操作变得更加直观和方便。

传统匿名方法的写法:

lambda 表达式 之前,如果要实现相同的功能,可能会用如下的代码:

bool exists = items.Any(delegate(iteminfo item) {
    return item.id == 1001;
});

使用 lambda 表达式 后,代码简化为: 

bool exists = items.Any(item => item.id == 1001);

这个语法更简洁,更易读,也减少了代码的冗余。

Lambda 表达式的结构:

Lambda 表达式 的语法是 (参数) => { 表达式或代码块 },其中:

  • 参数 是传递给匿名函数的输入参数,在 LINQ 中通常是集合的单个元素。
  • =>lambda 运算符,表示从参数到函数体的映射。
  • { 表达式或代码块 } 是函数体,可以是单个表达式(返回值)或一个代码块。
var numbers = new List<int> { 1, 2, 3, 4, 5 };

// 使用 Lambda 表达式查找偶数
bool hasEven = numbers.Any(n => n % 2 == 0);

// Lambda 表达式中的 `n` 是 List<int> 的每个元素,类似于传统循环中的 `foreach (var n in numbers) { }`

在这个例子中,n => n % 2 == 0 是一个 lambda 表达式,它接受集合中的每一个 int 元素 n,并检查这个元素是否为偶数。

总结:

  • Lambda 表达式 是为了简化代码并与 LINQ 紧密结合的一种语法。
  • 表达式中的参数表示集合中的单个元素。
  • 通过这种语法,你可以简洁地定义对集合每个元素的操作,从而更方便地对集合进行过滤、查询等操作。

为什么不用填上参数类型

在 C# 的 lambda 表达式 中,可以不用显式指定参数类型的原因,源于编译器的类型推断机制。

类型推断的原理

LINQ 方法(如 AnyWhereSelect 等)的使用过程中,lambda 表达式 所操作的对象是某个集合中的元素,而这个集合的元素类型是明确的。因此,编译器能够自动推断出 lambda 表达式 参数的类型。

List<iteminfo> items = new List<iteminfo>();

// 使用 lambda 表达式查找 id 为 1001 的元素
bool exists = items.Any(item => item.id == 1001);

在这个例子中,items 是一个 List<iteminfo>,编译器知道 List<iteminfo> 中的元素类型是 iteminfo,所以在 item => item.id == 1001 中,item 的类型自动被推断为 iteminfo

类型推断的好处

  1. 代码简洁:你不必重复写类型信息,代码更加简洁、易读。
  2. 减少冗余:避免不必要的类型声明,可以使代码更加清晰,尤其在复杂的查询表达式中。

需要显式指定类型的情况

虽然通常编译器可以推断出参数类型,但在某些情况下,显式指定参数类型可能是必要的。例如:

  1. 当编译器无法推断类型时:如果类型推断不明确,编译器可能会要求你显式地指定类型。
  2. 使用复杂类型或匿名类型:有时候,显式声明类型可以让代码更清晰,尤其在涉及复杂的或不常见的类型时。

显式指定参数类型的方式

如果你愿意,也可以显式指定参数的类型。显式指定参数类型时,需要使用括号包裹参数:

bool exists = items.Any((iteminfo item) => item.id == 1001);
bool exists = items.Any((iteminfo item) => {return item.id == 1001;
});也可以

在这个例子中,iteminfoitem 的类型。这种写法与前面不显式指定类型的写法功能相同,只是显式地告诉编译器 item 的类型是 iteminfo

总结

  • 类型推断:编译器可以通过 lambda 表达式 的上下文自动推断参数的类型,因此你通常不需要显式指定类型。
  • 代码简化:类型推断机制让代码更简洁,减少了不必要的冗余。
  • 灵活性:在需要时,你仍然可以显式地指定参数类型,以提高代码的可读性或解决推断问题。

查找 List<iteminfo>里是否存在某个值

1. 使用 Any 方法

Any 方法用于确定集合中是否存在满足指定条件的元素。如果存在则返回 true,否则返回 false

bool exists = items.Any(item => item.id == 1001);

 这里的item指的是List的items的单个个体

AnyFirstOrDefaultWhere 等方法中的 lambda 表达式中,item => item.id == 1001item 代表 List 中的每个单独的元素。

你可以给这个参数取任何名字,只要它能清晰地表达你的意图,并且在 lambda 表达式中使用一致即可。

2. 使用 FirstOrDefault 方法

FirstOrDefault 方法用于查找第一个满足条件的元素,如果不存在这样的元素,则返回 null 或类型的默认值。

iteminfo foundItem = items.FirstOrDefault(item => item.id == 1001);

你可以通过检查 foundItem 是否为 null 来判断是否找到了满足条件的元素。

3. 使用 Where 方法(如果需要获取所有匹配项

如果可能有多个 id1001 的项,并且你想获取所有这些项,可以使用 Where 方法。

List<iteminfo> matchingItems = items.Where(item => item.id == 1001).ToList();

 

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

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

相关文章

Mac环境下OpenTest使用总结

运行环境&#xff1a; node&#xff1a;20.5.1 npm&#xff1a;10.5.0 Java&#xff1a;1.8.0_351(如果存在多个版本Java&#xff0c;安装前将环境切换到jdk8) 安装 在终端输入命令 npm install opentest -g 开始 新建终端&#xff0c;输入命令&#xff1a; cd ~ mkdi…

视频转文字提取的7种工具,简单快速高效

视频内容的迅速增长让我们既享受了视觉盛宴&#xff0c;也面临着信息整理的挑战。很多时候我们看到一段文案内容很精彩的视频&#xff0c;想要记录里面的文字&#xff0c;你是不是听一句写一句呢&#xff1f;那样会非常耗费时间&#xff0c;如何将视频中的精华内容快速转化为可…

Python机器学习——人脸性别识别

一、选题背景 人脸识别技术是模式识别和计算机视觉领域最富挑战性的研究课题之一&#xff0c;也是近年来的研究热点&#xff0c;人脸性别识别作为人脸识别技术的重要组成部分也受到了广泛地关注。人脸性别识别就是向计算机输入人脸图像&#xff0c;经过某种方法或运算&#xff…

springboot图书商城

1.可注册可登录 2.首页-》可浏览热销图书&#xff0c;可查看用户发布的帖子&#xff0c;可查看热门资讯 3.图书商城-》图书详情&#xff0c;可购买&#xff0c;可加入购物车&#xff0c;可展示评价 4.图书贴吧-》可查看用户发布的帖子&#xff0c;可留言评论 5.平台资讯-》可查…

BugKu练习记录:小山丘的秘密

题目&#xff1a; hill能有什么秘密呢 bugku{PLGTGBQHM} 其中A1&#xff0c;flag全为小写hill解密&#xff0c;a1&#xff0c;所以z0&#xff0c;字母表为zabcdefghijklmnopqrstuvwxy&#xff0c;根据图片上的棋子数得到对应的字母&#xff0c;分别是abczadefz&#xff0c;用工…

无头结点单链表直接插入排序(王红梅分级抽象教学方法)

struct ListNode {int val;struct ListNode* next; };typedef struct ListNode ListNode; struct ListNode* insertionSortList(struct ListNode* head) {// 如果链表为空或者链表只有一个元素&#xff0c;那就根本不用排序if (head NULL || head->next NULL)return head…

C++入门基础知识45——【关于C++ 函数】定义函数、函数声明

成长路上不孤单&#x1f60a;【14后&#xff0c;C爱好者&#xff0c;持续分享所学&#xff0c;如有需要欢迎收藏转发&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#xff01;&#xff01;&#xff01;&#xff01;&#xff…

海外广告投放成功的关键点有哪些?

在全球化日益加深的今天&#xff0c;海外广告投放已成为众多企业拓展国际市场、提升品牌影响力的关键手段。然而&#xff0c;面对不同文化、语言、消费习惯以及市场环境的挑战&#xff0c;如何确保海外广告投放的成功&#xff0c;是每一个跨境营销者面对的重大课题。本文将从多…

曹启富主任医师:高血压的罪魁祸首找到啦!原来是他变硬了

上周公司一年一度的体检&#xff0c;如同一场无声的健康大考&#xff0c;本以为不过是例行公事&#xff0c;走走过场&#xff0c;没想到却意外揭开了许多同事健康背后的隐忧。平日里自诩年轻力壮、身体倍儿棒的他们&#xff0c;体检报告上却赫然出现了多个警示灯&#xff0c;让…

开放式耳机是什么意思?开放式耳机好不好用?

开放式耳机是一种在设计上不会完全封闭或堵塞耳道的耳机类型 。其发声原理通常是通过空气传导和骨传导的组合&#xff0c;将声音传递到内耳&#xff0c;并刺激听觉神经产生听觉感受 。 优点&#xff1a; 佩戴舒适&#xff1a;通常采用轻盈的设计&#xff0c;不会直接刺激耳膜&…

心脑血管科曹启富主任医师:低压高的2大原因!年轻人血压高一定要看

在现代社会&#xff0c;不仅仅是中老年人&#xff0c;越来越多的年轻人也开始面临血压低压&#xff08;舒张压&#xff09;偏高的问题。这一现象往往被忽视&#xff0c;但其潜在的健康风险却不容忽视。了解低压高的原因&#xff0c;对于年轻人维护心血管健康至关重要。本文将深…

海外社交媒体引流策略及云手机的应用

在外贸电商领域&#xff0c;海外社交媒体引流已成为一种极为有效的营销手段。通过精准锁定目标受众&#xff0c;企业能够以较低成本获取大量流量&#xff0c;从而提高转化率。在这个过程中&#xff0c;云手机的应用也越来越受到重视。 首先&#xff0c;我们需要选择适合的海外社…

工作录屏工具选择全攻略:哪种录屏工具更得你心?

在如今这个信息爆炸的时代&#xff0c;电脑录屏工具已经成为我们工作中不可或缺的利器。无论是制作教程、演示操作还是记录重要时刻&#xff0c;一款好的录屏工具都能让我们的工作事半功倍。接下来&#xff0c;为大家推荐几款工作中常用的电脑录屏工具&#xff0c;并分享使用感…

Neo4j在Ubuntu 20.04上安装

rootnode11:~# cat /etc/lsb-release DISTRIB_IDUbuntu DISTRIB_RELEASE20.04 DISTRIB_CODENAMEfocal DISTRIB_DESCRIPTION"Ubuntu 20.04.6 LTS" rootnode11:~# cat /etc/issue Ubuntu 20.04.6 LTS \n \l 1.安装jdk java 1.8.xx版本对应neo4j 3.xx版本 jdk 11版本对…

CpK vs PpK,过程能力指标的精彩对决

Cpk VS Ppk&#xff08;一&#xff09;描述 对于Cpk和Ppk这两个概念&#xff0c;大家可能会有无数个疑问&#xff01;这两个指标我该看哪个&#xff1f;计算有什么差别……那么我们首先来看一下Minitab中对它们俩是怎么描述的。 大多数能力评估都可以分组为以下两种类别中的一…

区块链未来发展展望:机遇与挑战并存

前言 随着全球数字化进程的不断推进&#xff0c;区块链技术作为一种去中心化、安全性高、透明度强的分布式账本技术&#xff0c;正逐步融入各个领域并产生深远影响。近年来&#xff0c;区块链已经从初期的加密货币应用扩展到金融、供应链管理、医疗健康、物联网、能源等多个行…

位图(布隆过滤器)

bitset/bitmap 给40亿个不重复的无符号整数&#xff0c;没排过序。给1个无符号整数,如何快速判断一个数是否在这40亿个数中。 ​ #pragma once#include <vector> #include <string> #include <time.h>template<size_t N> class bitset { public:bitse…

实战docker第一天——windows安装docker,测试,并解决被墙办法

Docker 是一个开源的容器化平台&#xff0c;它允许开发者将应用程序及其所有依赖项打包在一个名为“容器”的单独环境中&#xff0c;从而确保应用程序在任何环境下都能一致地运行。以下是 Docker 的一些核心概念及其意义&#xff1a; 容器化&#xff1a;Docker 通过将应用程序及…

外卖霸王餐系统的运作流程及注意事项

霸王餐系统概述 一、系统组成 商家端发布霸王餐活动信息&#xff0c;包括菜品、时间、人数等。管理活动报名者信息。查看活动效果和用户反馈。用户端浏览和报名感兴趣的霸王餐活动。提交评价和反馈。管理后台审核商家和用户信息。监控活动流程和数据。 二、运作流程 1.商家…

去中心化网络:Web3如何颠覆传统互联网

在互联网的演进过程中&#xff0c;从最初的静态网页到交互式的Web2.0&#xff0c;技术的进步不断推动着网络的变革。而如今&#xff0c;Web3作为互联网的下一代技术&#xff0c;正以其去中心化的特性&#xff0c;逐步颠覆传统的互联网架构。本文将深入探讨Web3如何通过去中心化…