using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public struct TestRef
{
public int atk;
public int def;
public TestRef(int atk, int def)
{
this.atk = atk;
this.def = def;
}
}
public class Lesson8 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
#region 知识点一 C#7对应的Unity版本
//Unity 2018.3支持C# 7
//Unity 2019.4支持C# 7.3
//7.1, 7.2, 7.3相关内容都是基于 7的一些改进
#endregion
#region 知识点二 C#7的新增功能和语法有哪些
//1.字面值改进
//2.out 参数相关 和 弃元知识点
//3.ref 返回值
//4.本地函数
//5.抛出表达式
//6.元组
//7.模式匹配
#endregion
#region 知识点三 字面值改进
//基本概念:在声明数值变量时,为了方便查看数值
// 可以在数值之间插入_作为分隔符
//主要作用:方便数值变量的阅读
int i = 9_9123_1239;
print(i);
int i2 = 0xAB_CD_17;
print(i2);
#endregion
#region 知识点四 out变量的快捷使用 和 弃元
//用法:不需要再使用带有out参数的函数之前,声明对应变量
//作用:简化代码,提高开发效率
//1.以前使用带out函数的写法
//int a;
//int b;
//Calc(out a, out b);
//2.现在的写法
Calc(out int x, out int y);
print(x);
print(y);
//3.结合var类型更简便(但是这种写法在存在重载时不能正常使用,必须明确调用的是谁)
Calc(out int a, out var b);
print(a);
print(b);
//4.可以使用 _弃元符号 省略不想使用的参数
Calc(out int c, out _);
print(c);
#endregion
#region 知识点五 ref修饰临时变量和返回值
//基本概念:使用ref修饰临时变量和函数返回值,可以让赋值变为引用传递
//作用:用于修改数据对象中的某些值类型变量
//1.修饰值类型临时变量
int testI = 100;
ref int testI2 = ref testI;
testI2 = 900;
print(testI);
TestRef r = new TestRef(5,5);
ref TestRef r2 = ref r;
r2.atk = 10;
print(r.atk);
//2.获取对象中的参数
ref int atk = ref r.atk;
atk = 99;
print(r.atk);
//3.函数返回值
int[] numbers = new int[] { 1, 2, 3, 45, 5, 65, 4532, 12 };
ref int number = ref FindNumber(numbers, 5);
number = 98765;
print(numbers[4]);
#endregion
#region 知识点六 本地函数
//基本概念:在函数内部声明一个临时函数
//注意:
//本地函数只能在声明该函数的函数内部使用
//本地函数可以使用声明自己的函数中的变量
//作用:方便逻辑的封装
//建议:把本地函数写在主要逻辑的后面,方便代码的查看
print(TestTst(10));
#endregion
#region 总结
//C#7的新语法更新重点主要是 代码简化
//今天学习的out和ref新用法,弃元、本地函数都是相对比较重要的内容
//可以给我们带来很多便捷性
#endregion
}
public int TestTst(int i)
{
bool b = false;
i += 10;
Calc();
print(b);
return i;
void Calc()
{
i += 10;
b = true;
}
}
public ref int FindNumber(int[] numbers, int number)
{
for (int i = 0; i < numbers.Length; i++)
{
if (numbers[i] == number)
return ref numbers[i];
}
return ref numbers[0];
}
public void Calc(out int a, out int b)
{
a = 10;
b = 20;
}
public void Calc(out float a, out float b)
{
a = 10;
b = 20;
}
// Update is called once per frame
void Update()
{
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson9 : MonoBehaviour
{
public (int, float) yz;
// Start is called before the first frame update
void Start()
{
#region 知识点一 抛出异常
// throw 知识回顾
// 抛出异常表达式用于主动抛出一个异常
// 一般使用方式:throw + new一个异常对象
// 异常类:Exception
// throw new NullReferenceException("1231231");
#region C# 内置异常
// 常见异常类型:
// IndexOutOfRangeException:当数组下标越界时抛出
// NullReferenceException:当访问空对象时抛出
// ArgumentException:参数非法
// ArgumentNullException:传递了空参数
// ArgumentOutOfRangeException:参数值超出范围
// SystemException:系统级异常基类
// OutOfMemoryException:内存不足
// StackOverflowException:栈溢出
// ArithmeticException:算术运算错误
// ArrayTypeMismatchException:数组类型不匹配
// BadImageFormatException:图像格式错误
// DivideByZeroException:除以零错误
// DllNotFoundException:找不到DLL文件
// FormatException:格式错误
// InvalidCastException:无效的类型转换
// InvalidOperationException:操作在当前状态下无效
// MethodAccessException:访问权限不足
// MissingMemberException:缺少成员
// NotFiniteNumberException:非有限数值
// NotSupportedException:不支持的操作
// InvalidOperationException:对象状态无效时调用方法
#endregion
// 在C# 7中,可以在更多表达式中进行异常抛出
// 优点:简化代码
// 1. 空合并运算符中使用throw
// InitInfo("123");
// 2. 条件运算符中使用throw
// GetInfo("1,2,3", 4);
// 3. =>符号函数直接throw
// Action action = () => throw new Exception("出错了,准备接受纪委调查");
// action();
#endregion
#region 知识点二 元组
// 核心作用:值的集合,提供快速创建数据结构的方式
// 常用于函数需要返回多个值时,语法:(返回值1类型, 返回值2类型, ...)
// 函数内部返回时使用 (返回值1, 返回值2, ...)
// 1. 无命名元组声明(通过ItemN访问)
(int, float, bool, string) yz = (1, 5.5f, true, "123");
print(yz.Item1);
print(yz.Item2);
print(yz.Item3);
print(yz.Item4);
// 2. 具名元组声明
(int i, float f, bool b, string str) yz2 = (1, 5.5f, true, "123");
print(yz2.i);
print(yz2.f);
print(yz2.b);
print(yz2.str);
// 3. 元组支持==和!=比较
// 按顺序比较每个成员,全部相等则返回true
if (yz == yz2)
print("相等");
else
print("不相等");
// 元组不能作为字段类型,但成员可以访问
// print(this.yz.Item1);
#region 元组应用:多返回值
// 无命名方式接收返回值
var info = GetInfo();
print(info.Item1);
print(info.Item2);
print(info.Item3);
// 具名方式
print(info.f);
print(info.i);
print(info.str);
// 元组解构赋值
int myInt;
string myStr;
float myFloat;
(myStr, myInt, myFloat) = GetInfo();
// 或直接声明类型
// (string myStr, int myInt, float myFloat) = GetInfo();
print(myStr);
print(myInt);
print(myFloat);
// 忽略部分返回值
(string ss, _, _) = GetInfo();
print(ss);
#endregion
#region 元组应用:字典键
// 使用元组作为复合键
Dictionary<(int i, float f), string> dic = new Dictionary<(int i, float f), string>();
dic.Add((1, 2.5f), "123");
if(dic.ContainsKey((1, 2.5f)))
{
print("存在相同键");
print(dic[(1, 2.5f)]);
}
#endregion
#endregion
#region 知识点三 模式匹配
// 核心作用:通过语法元素检测值是否符合某种模式,并提取信息
// 在C#7中增强:
// 1. is表达式增强
// 2. switch语句的case模式
// 优点:简化类型检查和值提取
// 1. 常量模式(is判断值)
object o = 1.5f;
if(o is 1)
{
print("o等于1");
}
if(o is null)
{
print("o是null");
}
// 2. 类型模式(is + 变量声明,case类型)
// 直接判断类型并赋值给变量
if (o is int i)
{
print(i);
}
switch (o)
{
case int value:
print("int:" + value);
break;
case float value:
print("float:" + value);
break;
case null:
print("null");
break;
default:
break;
}
// 3. var模式:将值存入新变量
if(o is var v)
{
print(o);
}
#endregion
#region 总结
// 元组和模式匹配是C#7的重要特性
// 可提高代码效率和简洁性
// 建议多加练习
#endregion
}
private (string str, int i, float f) GetInfo()
{
return ("123", 2, 5.5f);
}
private string jsonStr;
private void InitInfo(string str) => jsonStr = str ?? throw new ArgumentNullException(nameof(str));
private string GetInfo(string str, int index)
{
string[] strs = str.Split(',');
return strs.Length > index ? strs[index] : throw new IndexOutOfRangeException();
}
// Update is called once per frame
void Update()
{
}
}