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. #树,搜索#NOIP2020.9.26模拟tom

    分析 考虑最极端的情况也就是TOM天天吃早餐肠或者晚餐肠, 那么早餐肠和晚餐肠应分别构成一个互不相交连通块, 所以题目转换成是否有一个点的子树大小为\(a\)或\(b\), 将这个点与它父亲的边断开就 ...

  2. #树状数组、dp#JZOJ 5361 捕老鼠

    题目 农夫约的农庄里有\(N\)个仓库,排成了一排,编号为\(1-N\). 假设猫在第\(i\)个仓库点燃艾条,烟雾就会充满该仓库,并向左右扩散\(Ai\)的距离,接着所有\(|i-j|<=Ai ...

  3. OpenHarmony 3.2 Beta1版本正式发布

    5 月 31 日,开放原子开源基金会正式发布 OpenAtom OpenHarmony(以下简称"OpenHarmony")3.2 Beta1 版本.   全球开发者可通过Gite ...

  4. C# 介绍、应用领域、入门、语法、输出和注释详解

    什么是 C#? C#(发音为"C-Sharp")是一种由 Microsoft 创建的面向对象的编程语言,运行在 .NET Framework 上.源于 C 家族,与流行的语言如 C ...

  5. Qt Create开发,修改 .Pro 文件改变 exe 的名称

    // .pro // 修改 TARGET 就可以改变生成的exe的名称 TARGET = Test // 要是生成的exe名称中需要带有空格,需要用到$$quote TARGET = $$quote( ...

  6. 第十九篇:Django ORM外键关联关系

    一.一对多的创建 二.一对多跨表操作 三.创建多对多 四.Ajax处识 五.模板继承与导入 六.自定义分页

  7. 演示webuploader和cropperjs图片裁剪上传

    最近有个项目要在浏览器端裁剪并上传图片.由于缺乏人力,只能我上阵杀敌.通过参考各种文章,最后决定用cropperjs进行图片裁剪,用webuploader上传文件.本文涉及到的知识至少有Java基础. ...

  8. 嘉楠k210 kd233官方demo板gpio点灯实验

    使用maixpy  micropython开发 import utime from Maix import GPIO from board import board_info from fpioa_m ...

  9. Kubernetes API 编程利器:Operator 和 Operator Framework

    本文整理自<CNCF x Alibaba 云原生技术公开课>第 24 讲,点击"阅读原文"直达课程页面. 关注"阿里巴巴云原生"公众号,回复关键词& ...

  10. 飞天大数据产品价值解读— SaaS模式云数据仓库MaxCompute

    飞天大数据产品价值解读 - SaaS模式云数据仓库 MaxCompute摘要:企业在数字化转型过程中面临数据技术平台建设和运营的诸多挑战,随着现代化数据仓库向多功能.服务化方向发展演进,技术侧的变革为 ...