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. redis 简单整理——HyperLogLog[十三]

    前言 简单介绍一下HyperLogLog. 正文 HyperLogLog并不是一种新的数据结构(实际类型为字符串类型),而 是一种基数算法,通过HyperLogLog可以利用极小的内存空间完成独立总数 ...

  2. python异步正则字符串替换,asyncio异步正则字符串替换re

    自然语言处理经常使用re正则模块进行字符串替换,但是文本数量特别大的时候,需要跑很久,这就需要使用asyncio异步加速处理 import pandas as pd import re import ...

  3. Oracle 数据库误删操作闪回

    Oracle 数据库误删操作闪回 闪回功能是内置的,类似于服务器快照,看运气要在的数据在不在 select * from testtable as of timestamp to_timestamp( ...

  4. 暑期集训 Day12 —— 模拟赛复盘

    ${\color{Green} \mathrm{Problem\ 1 :Subarray }} $ Map. ${\color{Green} \mathrm{Problem\ 2 :小z玩游戏 }} ...

  5. IDC:云效产品能力No.1,领跑中国DevOps市场

    简介: 近日,全球领先的专业市场调查机构国际数据公司(IDC)发布了<IDC MarketScape:中国 DevOps 平台市场厂商评估,2022>报告.此报告中对中国主流 DevOps ...

  6. 技术解读:英特尔 x86 平台上,AI 能力是如何进行演进的?(附PPT)

    ​简介:AI 生态系统是怎样的?其中又有哪些关键技术? AI 计算力的指数增长意味着,为了解决越来越复杂的用例,即使是 1000 倍的计算性能增长也很容易被消耗.因此,需要通过软件生态系统的助力,才能 ...

  7. 重温设计模式之 Factory

    简介: 创建型模式的核心干将,工厂.简单工厂.抽象工厂,还记得清么,一文回顾和对比下. 作者 | 弥高来源 | 阿里技术公众号 前言 创建型模式的核心干将,工厂.简单工厂.抽象工厂,还记得清么,一文回 ...

  8. [ML] 机器学习简介

    监督学习(Supervised Learning) 添加标签,手把手训练. 比如线性回归算法. 半监督学习(Semi-supervised Learning) 非监督学习(Unsupervised L ...

  9. [Go] freecache 设置 SetGCPercent 的作用

    你需要对 freecache 有一个大致了解,freecache 的内存空间是预分配的. 假设你的程序占用了 50M 内存,那么开启 freecache 预分配 200M 空间,总共下来就是 250M ...

  10. 2019-8-31-dotnet-线程静态字段

    title author date CreateTime categories dotnet 线程静态字段 lindexi 2019-08-31 16:55:58 +0800 2019-06-13 0 ...