1.ref的一些运用

1.1 ref readonly

关于ref,一个主要应用是防止结构体拷贝,若返回的结构体不需要修改则用ref readonly,类似c++的const标记 :

private ref readonly Attr PlayerSetting(Player player)
{
return ref player.attr;
}

1.2 array ref

由于索引器不支持ref,所以目前只有数组的元素可以用ref:

int[] arr = new[] {1, 2, 3};
ref int item = ref arr[0];
//可用 //List<int> list = new List<int>();
//ref int item = ref list[0];
//报错

1.3 属性ref(返回值ref)

可以借由ref返回值的支持,给属性加上该关键字,以提示使用者优先考虑用ref方法读写

public class Player
{
private int mHp; public ref int Hp => ref mHp;
}

1.4 多值ref

目前返回值不支持多ref返回,解构功能也不支持ref,但由于委托参数支持ref,因此可间接实现多字段ref编辑

使用:

RefStructTest refStructTest = new RefStructTest();
refStructTest.SetValues((ref int x, ref float y, ref float z, ref bool w) =>
{
x = 24;
y = 12.0f;
z = 6.0f;
w = true;
});

定义:

public delegate void RefTestValueSet(ref int x, ref float y, ref float z, ref bool w);

public struct RefStructTest
{
public int a;
public float b;
public float c;
public bool d; public void SetValues(RefTestValueSet set)
{
set(ref a, ref b, ref c, ref d);
}
}

2.struct fixed的一些运用

fixed关键字可以固定内存地址,从而使用指针访问该地址,struct中的fixed字段可以实现struct内直接包含数组,

而不是链接到堆内存的数组。struct微软建议是将大小控制在16字节(后来也有24字节说法)以内,虽然可以配合ref做到不频繁拷贝,

但目前还没有明确的资料确定不会产生性能影响。

官方文档的fixed页面里也没有看见,所以谨慎使用吧。

通常指针和栈集合的分配可以使用spin,但unity目前没有集成spin以及对应的dll。

(也可以参考ZString(https://github.com/Cysharp/ZString),把相关dll丢进来用)

fixed本身并不是一个新功能,但在7.x版本后对其进行了增强。

unity可以通过AssemblyDefinition实现局部的unsafe code功能,下面的一些unsafe特性代码也是定义

在一个unsafe库中。

2.1 一个理论上可以实现的栈数组

public unsafe struct StructArray
{
private fixed int arr[8]; public void SetArr(int index, int value)
{
arr[index] = value;
} public ref int GetArrValue(int index)
{
return ref arr[index];
}
}

通过函数接口的调用,外部代码不需要访问指针即可在栈中使用数组,

简单的测试一下:

StructArray structArray = new StructArray();
structArray.SetArr(0, 10);
structArray.SetArr(1, 20);
structArray.SetArr(2, 30); Debug.Log(structArray.GetArrValue(0));//10
Debug.Log(structArray.GetArrValue(1));//20
Debug.Log(structArray.GetArrValue(2));//30

2.2 一个简单的栈string结构

因为string是个分配在堆上的结构,且修改会重新创建,有性能开销。

因此有许多优化string的方案,这里我们可以分配栈上的char[]来做一些优化(测试代码,只支持8个字符):

using System;

public unsafe struct StructString
{
private fixed char arr[8]; public void SetString(string str)
{
fixed (char* dstPtr = arr)
{
fixed (char* srcPtr = str)
{
Buffer.MemoryCopy(srcPtr, dstPtr, 16L, 16L);
}
}
} public string GetString()
{
string result = string.Empty;
fixed (char* ptr = arr)
{
result = new string(ptr);
} return result;
} public bool EqulasCheck(StructString other)
{
bool result = true; fixed (char* xPtr = &arr[0])//16字节,只需要做2次long类型判断
{
char* yPtr = other.arr; if (*(long*) xPtr != *(long*) yPtr)
{
result = false;
}
else if (*(long*) (xPtr + 4) != *(long*) (yPtr + 4))
{
result = false;
}
} return result;
}
}

使用:

StructString str = new StructString();
str.SetString("qwe");//qwe
Debug.Log(str.GetString()); StructString str2 = new StructString();
str2.SetString("qwe");//true
Debug.Log(str.EqulasCheck(str2));

可以看见,封装之后外部代码可以不接触unsafe、指针这些内容。以上就是对这几样新功能的可用范围进行思考并编写的一些

小案例。

学习c# 7.0-7.3的ref、fixed特性并在Unity下测试的更多相关文章

  1. 嵌入式Linux学习笔记(0)基础命令。——Arvin

    学习记录: 到今天为止ARM裸机开发学习进程:1.2.1-1.2.14 预科班知识Linux介绍学习进程:0.2.1-0.2.6 学习内容笔记: 学习了Linux的开发方式的优劣介绍 学习了常用文件夹 ...

  2. Find security bugs学习笔记V1.0

    Find security bugs学习笔记V1.0 http://www.docin.com/p-779309481.html

  3. PHP代码安全学习笔记V1.0

    PHP代码安全学习笔记V1.0http://www.docin.com/p-778369487.html

  4. Java安全防御学习笔记V1.0

    Java安全防御学习笔记V1.0http://www.docin.com/p-766808938.html

  5. Common Lisp学习笔记(0):从SLIME开始 | 优哉·幽斋

    Common Lisp学习笔记(0):从SLIME开始 | 优哉·幽斋 Common Lisp学习笔记(0):从SLIME开始

  6. 新手可以学习cocos2dx 3.0 组态(两)

    这主要是关于cocos3.0 组态,鉴于互联网已经有很多这样的文章.所以我简单谈一下: 1.python2.7 因为cocos目新建是用python脚本做的,至于为什么不用python3.x  那么请 ...

  7. ArcGIS API for JavaScript 4.2学习笔记[0] AJS4.2概述、新特性、未来产品线计划与AJS笔记目录

    放着好好的成熟的AJS 3.19不学,为什么要去碰乳臭未干的AJS 4.2? 4.2全线基础学习请点击[直达] 4.3及更高版本的补充学习请关注我的博客. ArcGIS API for JavaScr ...

  8. Python3学习之路~0 目录

    目录 Python3学习之路~2.1 列表.元组操作 Python3学习之路~2.2 简单的购物车程序 Python3学习之路~2.3 字符串操作 Python3学习之路~2.4 字典操作 Pytho ...

  9. 在业务逻辑中,经常会有父组件调用子组件方法的情况,vue2.0 和 vue3.0 的使用中有些不一样,在这里总结下。

    在业务逻辑中,经常会有父组件调用子组件方法的情况,vue2.0 和 vue3.0 的使用中有些不一样,在这里总结下. vue2.0 中的使用方法 父组件: <template> <d ...

  10. atitit.Servlet2.5 Servlet 3.0 新特性 jsp2.0 jsp2.1 jsp2.2新特性

    atitit.Servlet2.5 Servlet 3.0 新特性 jsp2.0 jsp2.1 jsp2.2新特性   1.1. Servlet和JSP规范版本对应关系:1 1.2. Servlet2 ...

随机推荐

  1. 欢迎体验BotBattle!

    目录 1.常规游玩 2.快速开始 3.规则介绍 3.推荐的示例代码 1.常规游玩 前往复制 最基础代码 到剪切板 这有助于您开始游戏,且对于您熟悉 Bot 代码的 I/O 进而创建其他 bot 很有意 ...

  2. 为什么 L1 正则化能做特征选择而 L2 正则化不能

    假设我们的模型只有一个参数 \(w\),损失函数为 \(L(w)\),加入 L1 和 L2 正则化后的损失函数分别记为 \(J_1(w), J_2(w)\): \[\begin{gathered} J ...

  3. Spring 框架模块深度解析:核心容器、数据访问、Web 层与其他关键模块

    Spring 可能成为您的所有企业应用程序的一站式商店.但是,Spring 是模块化的,允许您挑选适用于您的模块,而无需引入其他模块.下面的部分提供了 Spring Framework 中所有可用模块 ...

  4. Python 函数:定义、调用、参数、递归和 Lambda 函数详解

    函数是一段代码块,只有在调用时才会运行.您可以将数据(称为参数)传递给函数. 函数可以返回数据作为结果. 创建函数 在Python中,使用def关键字定义函数: 示例 def my_function( ...

  5. HDD与你相约深圳,一起探讨创新开发与运营增长

    12月14日,HUAWEI Developer Day(以下简称HDD)将在深圳与广大开发者见面.本次HDD共设有主论坛.两个分论坛及两个闭门会议,期待各位开发者前来参加. 精彩预告 01·主论坛 在 ...

  6. Python从 requirements.txt 安装库

    pip install -r requirements.txt

  7. HarmonyOS SDK 助力新浪新闻打造精致易用的新闻应用

    原生智能是HarmonyOS NEXT的核心亮点之一,依托HarmonyOS SDK丰富全面的开放能力,开发者只需通过几行代码,即可快速实现AI功能.新浪新闻作为鸿蒙原生应用开发的先行者之一,从有声资 ...

  8. 开发指导—利用组件&插值器动画实现HarmonyOS动效

    一. 组件动画 在组件上创建和运行动画的快捷方式.具体用法请参考通用方法. 获取动画对象 通过调用animate方法获得animation对象,animation对象支持动画属性.动画方法和动画事件. ...

  9. mysql 必知必会整理—游标[十四]

    前言 简单介绍一下游标. 正文 需要MySQL 5 MySQL 5添加了对游标的支持,因此,本章内容适用于MySQL 5及以后的版本. 有时,需要在检索出来的行中前进或后退一行或多行.这就是使用游标的 ...

  10. 【Oracle】预定义说明的部分 ORACLE 异常错误(EXCEPTION)

    预定义说明的部分 ORACLE 异常错误(EXCEPTION) 参考链接:https://www.cnblogs.com/thescentedpath/p/errordeal.html EXCEPTI ...