学习c# 7.0-7.3的ref、fixed特性并在Unity下测试
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下测试的更多相关文章
- 嵌入式Linux学习笔记(0)基础命令。——Arvin
学习记录: 到今天为止ARM裸机开发学习进程:1.2.1-1.2.14 预科班知识Linux介绍学习进程:0.2.1-0.2.6 学习内容笔记: 学习了Linux的开发方式的优劣介绍 学习了常用文件夹 ...
- Find security bugs学习笔记V1.0
Find security bugs学习笔记V1.0 http://www.docin.com/p-779309481.html
- PHP代码安全学习笔记V1.0
PHP代码安全学习笔记V1.0http://www.docin.com/p-778369487.html
- Java安全防御学习笔记V1.0
Java安全防御学习笔记V1.0http://www.docin.com/p-766808938.html
- Common Lisp学习笔记(0):从SLIME开始 | 优哉·幽斋
Common Lisp学习笔记(0):从SLIME开始 | 优哉·幽斋 Common Lisp学习笔记(0):从SLIME开始
- 新手可以学习cocos2dx 3.0 组态(两)
这主要是关于cocos3.0 组态,鉴于互联网已经有很多这样的文章.所以我简单谈一下: 1.python2.7 因为cocos目新建是用python脚本做的,至于为什么不用python3.x 那么请 ...
- ArcGIS API for JavaScript 4.2学习笔记[0] AJS4.2概述、新特性、未来产品线计划与AJS笔记目录
放着好好的成熟的AJS 3.19不学,为什么要去碰乳臭未干的AJS 4.2? 4.2全线基础学习请点击[直达] 4.3及更高版本的补充学习请关注我的博客. ArcGIS API for JavaScr ...
- Python3学习之路~0 目录
目录 Python3学习之路~2.1 列表.元组操作 Python3学习之路~2.2 简单的购物车程序 Python3学习之路~2.3 字符串操作 Python3学习之路~2.4 字典操作 Pytho ...
- 在业务逻辑中,经常会有父组件调用子组件方法的情况,vue2.0 和 vue3.0 的使用中有些不一样,在这里总结下。
在业务逻辑中,经常会有父组件调用子组件方法的情况,vue2.0 和 vue3.0 的使用中有些不一样,在这里总结下. vue2.0 中的使用方法 父组件: <template> <d ...
- 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 ...
随机推荐
- 欢迎体验BotBattle!
目录 1.常规游玩 2.快速开始 3.规则介绍 3.推荐的示例代码 1.常规游玩 前往复制 最基础代码 到剪切板 这有助于您开始游戏,且对于您熟悉 Bot 代码的 I/O 进而创建其他 bot 很有意 ...
- 为什么 L1 正则化能做特征选择而 L2 正则化不能
假设我们的模型只有一个参数 \(w\),损失函数为 \(L(w)\),加入 L1 和 L2 正则化后的损失函数分别记为 \(J_1(w), J_2(w)\): \[\begin{gathered} J ...
- Spring 框架模块深度解析:核心容器、数据访问、Web 层与其他关键模块
Spring 可能成为您的所有企业应用程序的一站式商店.但是,Spring 是模块化的,允许您挑选适用于您的模块,而无需引入其他模块.下面的部分提供了 Spring Framework 中所有可用模块 ...
- Python 函数:定义、调用、参数、递归和 Lambda 函数详解
函数是一段代码块,只有在调用时才会运行.您可以将数据(称为参数)传递给函数. 函数可以返回数据作为结果. 创建函数 在Python中,使用def关键字定义函数: 示例 def my_function( ...
- HDD与你相约深圳,一起探讨创新开发与运营增长
12月14日,HUAWEI Developer Day(以下简称HDD)将在深圳与广大开发者见面.本次HDD共设有主论坛.两个分论坛及两个闭门会议,期待各位开发者前来参加. 精彩预告 01·主论坛 在 ...
- Python从 requirements.txt 安装库
pip install -r requirements.txt
- HarmonyOS SDK 助力新浪新闻打造精致易用的新闻应用
原生智能是HarmonyOS NEXT的核心亮点之一,依托HarmonyOS SDK丰富全面的开放能力,开发者只需通过几行代码,即可快速实现AI功能.新浪新闻作为鸿蒙原生应用开发的先行者之一,从有声资 ...
- 开发指导—利用组件&插值器动画实现HarmonyOS动效
一. 组件动画 在组件上创建和运行动画的快捷方式.具体用法请参考通用方法. 获取动画对象 通过调用animate方法获得animation对象,animation对象支持动画属性.动画方法和动画事件. ...
- mysql 必知必会整理—游标[十四]
前言 简单介绍一下游标. 正文 需要MySQL 5 MySQL 5添加了对游标的支持,因此,本章内容适用于MySQL 5及以后的版本. 有时,需要在检索出来的行中前进或后退一行或多行.这就是使用游标的 ...
- 【Oracle】预定义说明的部分 ORACLE 异常错误(EXCEPTION)
预定义说明的部分 ORACLE 异常错误(EXCEPTION) 参考链接:https://www.cnblogs.com/thescentedpath/p/errordeal.html EXCEPTI ...