游戏开发乱七八糟的学习:C#的一些语法

一.C# 1~4的一些新功能

  1.命名参数:

void Start()
    {
        //命名参数可以实现打乱参数顺序,使用[参数名:]指定参数
        Test01(b: 2, c: 1, a: 0);

        //命名参数一般使用于有多个默认值的参数的情况
        Test02(1, p: 3);
    }

    private void Test01(int a, int b, int c)
    {

    }

    private void Test02(int m , int n = 2, int p = 3, int q = 4)
    {

    }

  2.动态类型

void Start()
    {
        //动态类型dynamic,这个类型在运行时检查类型
        //和var不同,var在编译时检查类型,也就是说,虽然我们写的是var类型,但是在编译时实际类型是明确的,编辑器中鼠标指到var上也能显示实际类型,而dynamic类型在编译时实际类型不明确,鼠标指到dynamic上不会显示实际类型
        //dynamic类型在编译时会编译为object类型,但是在代码中可以点出各种方法(和object的区别在于,dynamic可以是任意类型,并可以直接调用这个类型的所有方法,object类型需要转型)
        //dynamic类型可以用于替换反射操作
        dynamic a = 1;
        var b = 1;
        a.Test01(1, 2);//编辑器中并不会报错
    }

    private void Test01(int a, int b, int c)
    {

    }

 二.C# 5的一些新功能

  1.Task任务类

void Start()
    {
        //简介:Task是对线程的封装,以便更为方便地管理线程,一个task就是一个线程

        //创建task
        //方法一:直接new一个Task,需要传入线程执行地委托
        Task task01 = new Task(Test01);
        task01.Start();
        //方法二:使用静态方法Run创建task并直接开启
        var task02 = Task.Run(Test01);
        //方法三:使用Factory创建并直接开启
        var task03 = Task.Factory.StartNew(Test01);
        //说明:以上三种方式都可以通过泛型指定返回值,创建有返回值的task
        var task04 = Task.Run<int>(Test02);
        //通过Result获取返回值
        print(task04.Result);//注意:通过Result获取返回值时,如果此时task还没有执行得到返回值,主线程会阻塞等待task执行直到得到返回值;如果这时task是一个死循环,主线程会卡死

        //同步执行task
        //使用new创建的task可以同步执行
        var task05 = new Task(Test01);
        task05.RunSynchronously();//使用RunSynchronously方法同步执行线程,这种方式执行的线程主线程会等待其执行完毕再继续执行,和在主线程中执行代码类似

        //阻塞执行task
        var task06 = Task.Run(Test01);
        task06.Wait();//这个方法会让主线程在等待task06的逻辑执行完毕后再执行之后的代码
        Task.WaitAny(task01, task02, task03, task04, task05, task06);//这个方法会让主线程在等待传入的task中的任意一个任务完成后继续执行之后的代码
        Task.WaitAll(task01, task02, task03, task04, task05, task06);//这个方法会让主线程在等待传入的所有task都执行完成后再继续执行之后的代码

    }

    private void Test01()
    {

    }

    private int Test02()
    {
        return 1;
    }

   2.异步方法Async和await

//在方法名前使用async关键字标识这是一个异步方法
    //使用async修饰的函数中可以没有await关键字
    //异步方法名称建议以Async结尾
    //异步方法的返回值只能是void或者task
    //异步方法的变量不能使用ref或者out修饰
    private async void TestAsync()
    {
        //await经常和task配合使用
        //await可以开启一个新线程,并挂起异步方法,将控制权返回给调用者,等待开启的新线程逻辑执行完毕之后继续执行当前异步方法
        await Task.Run(
            () => 
            { 
                print($"新线程逻辑执行,当前时间:{Time.time}");
                Thread.Sleep(1000);
            });
        print($"异步方法执行完毕,当前时间:{Time.time}");
    }

    void Start()
    {
        TestAsync();

    }

三.C# 6的一些新功能

  1.静态导入

using UnityEngine;
//引用命名空间时,使用静态导入,之后可以直接访问其静态成员
using static UnityEngine.Mathf;

public class Test1 : MonoBehaviour
{
    void Start()
    {
        //静态导入了Mathf类后,可以直接不用指明类名就可以使用其中的方法
        Clamp01(0.5f);

    }
}

  2.异常筛选器

    void Start()
    {
        try
        {

        }
        //使用when关键字对捕获到的异常进行限制
        catch (Exception e) when (e.Message.Contains("301"))
        {

        }
        catch (Exception e) when (e.Message.Contains("404"))
        {

        }
        //最后一个catch可以不加when关键字进行筛选,意为使用默认方式处理剩余的异常
        catch (Exception e)
        {

        }
        finally
        {

        }
    }

  3.nameof关键字

    void Start()
    {
        int i = 0;
        //使用nameof关键字直接得到变量类型名称
        print(nameof(i));
        //也可以得到方法名
        print(nameof(List<int>.Add));
        //可以得到类名
        print(nameof(List<int>));
    }

 四.C# 7的一些新功能

  1.字面值改进

    void Start()
    {
        //在字面值上添加_作为分隔符方便阅读
        int i = 1_2345_6789;
    }

  2.out的快捷使用

void Start()
    {
        //在使用out参数时可以直接在给定参数的同时声明变量
        if(TryGetInt32(out var num))
        {
            print(num);
        }
    }

    private bool TryGetInt32(out int num)
    {
        num = 1;
        return true;
    }

  3.弃元

    void Start()
    {
        //使用_替换不想使用的out参数
        if(TryGetInt32(out _))
        {
            print("");
        }
    }

    private bool TryGetInt32(out int num)
    {
        num = 1;
        return true;
    }

  4.ref关键字将值类型改为引用类型

    void Start()
    {
        //使用ref关键字将值类型改为引用类型
        int i = 100;//值类型i
        ref int j = ref i;//引用类型j
    }

  5.本地函数

    void Start()
    {
        //直接使用本地函数
        int i = 0;
        Test();

        //本地函数,即函数中声明的函数,可以使用原函数中的所有局部变量
        void Test()
        {
            print(i);
        }
    }

  6.元组

    void Start()
    {
        //使用括号将多个变量组合成一个元组(相当于一个简单的结构体)
        (int, float, bool) i = (1, 2f, true);
        //使用item1\item2\item3...取用元组中的内容
        print($"{i.Item1}|{i.Item2}|{i.Item3}");

        //可以给元组中的元素取别名
        (int num, float time, bool health) j = (1, 2f, false);
        //使用别名取用
        print($"{j.num}|{j.time}|{j.health}");
    }

  7.模式匹配

    void Start()
    {
        //常量模式:[is 常量]用于判断是否是某个值
        int i = 1;
        if(i is 1)
        {
            print(i);
        }

        //类型模式:[is 类型名 变量名]用于判断变量是否是某个类型,是的话同时将其转型为新类型
        object j = 2;
        if(j is int k)
        {
            print(k);
        }
        //类型模式和switch语句的配合
        switch (j)
        {
            case int m:
                print(nameof(Int32));
                break;
            case float n:
                print(nameof(Single));
                break;
            case bool b:
                print(nameof(Boolean));
                break;
            default:
                print("");
                break;
        }

        //var模式:[is var 变量名]相当于将变量转存
        bool d = true;
        if(d is var e)
        {
            print(e.GetType().Name);
        }
    }
posted @ 2022-05-27 22:11  movin2333  阅读(122)  评论(0编辑  收藏  举报