ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

关于c# 7.0-7.3的ref、fixed特性在Unity下测试

2021-10-19 21:34:18  阅读:189  来源: 互联网

标签:int string c# arr 7.3 Unity fixed ref public


1.ref的一些运用

1.1 ref readonly

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

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编辑

定义:

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);
    }
}

使用:

RefStructTest refStructTest = new RefStructTest();
refStructTest.SetValues((ref int x, ref float b, ref float c, ref bool d) =>
{
    x = 24;
    b = 12.0f;
    c = 6.0f;
    d = true;
});

 

2.struct fixed的一些运用

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

而不是链接到堆内存的数组。struct微软建议是将大小控制在24字节以内,虽然可以配合ref做到不频繁拷贝,但目前还没有明确的资料

确定不会产生性能影响。官方文档的fixed页面里也没有看见,所以谨慎使用吧。

通常指针和栈集合的分配可以使用spin,但unity目前没有集成spin以及对应的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个字符):

public unsafe struct StructString
{
    private fixed char arr[8];


    public void SetString(string str)
    {
        fixed (char* ptr = str)
        {
            for (int i = 0; i < str.Length; i++)
            {
                if (i > 7) break;

                arr[i] = ptr[i];
            }
        }
    }

    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;

        for (int i = 0; i < 8; i++)
        {
            char x = arr[i];
            char y = other.arr[i];

            if (x != y)
            {
                result = false;
                break;
            }
        }

        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、指针这些内容。以上就是对这几样新功能的可用范围进行思考并编写的几个

小案例。最近比较忙就不做文章排版了,就当是记录吧。

标签:int,string,c#,arr,7.3,Unity,fixed,ref,public
来源: https://www.cnblogs.com/hont/p/15426547.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有