深入浅析C# 11 对 ref 和 struct 的改进

深入浅析C# 11 对 ref 和 struct 的改进

简介

C# 11 是微软新推出的一项编程语言的更新版本,其中包含了对于 ref 和 struct 的一些优化改进。此次改进旨在提高代码的运行效率并降低代码运行的堆内存的占用。为了能够更好地理解这些改进,需要先了解 ref 和 struct 的相关知识。

ref 和 struct

在 C# 中,ref 和 struct 都是比较重要的概念。ref 是 C# 中的一种引用类型,它使得在函数中可以直接对变量进行修改,而不需要进行复制,提高了代码的运行效率;而 struct 是一种值类型,可以被看作是一种轻量级的类,实例的分配不需要用到堆,减少了堆内存的使用。

C# 11 对 ref 和 struct 的改进

Span 结构体的支持

Span 是 C# 7 引入的一种结构体,但在 C# 11 中,其得到了更多的扩展。Span 不占用堆内存,其作用是“暴力”化简代码,并且可以更好地规避内存泄漏的风险。通过对其进行改进,使其在 ref / in 形式中提供更多的支持。

示例 1:以下代码使用 Span 进行内存拷贝:

int[] array = new int[] {1, 2, 3, 4, 5};
Span<int> span = array;
Span<int> subSpan = span.Slice(start: 2, length: 2);
int[] newArray = subSpan.ToArray();

示例 2:以下代码使用 Span 进行缓冲区写入操作:

using System.Buffers;

const int size = 1024;
using var memoryPool = MemoryPool<byte>.Shared;
using var rented = memoryPool.Rent(size);
try
{
    var memory = rented.Memory;
    var span = memory.Span;
    FillBuffer(span);
    ProcessBufferNew(ref MemoryMarshal.GetReference(span), span.Length);

    void FillBuffer(Span<byte> buffer)
    {
        for (int i = 0; i < buffer.Length; i++)
        {
            buffer[i] = (byte)i;
        }
    }

    unsafe void ProcessBufferNew(ref byte startRef, int length)
    {
        fixed (byte* ptr = &startRef)
        {
            // 使用指针 ptr 进行读写操作
        }
    }
}
finally
{
    memoryPool.Return(rented);
}

ref struct 和 readonly struct 的扩展

在 C# 11 中,ref struct 和 readonly struct 的限制得到了进一步的放松。现在,可以在这些结构体中添加实例字段(以前只能添加静态字段),并将它们作为方法的返回值和参数使用。

示例 3:以下代码展示了如何将 ref struct 作为参数传递,并以 ref 返回值的形式计算它们的总和。

ref struct Log
{
    public void LogStatus(string msg) { /* implement */ }
    public int TotalErrors { get; private set; }

    // added fields in C# 11
    private int ErrorCount;
    private int WarnCount;
    public void LogError() => ++ErrorCount;
    public void LogWarning() => ++WarnCount;    
}

void UsingRefStruct(in Log log, ref int totalErrors)
{
    log.LogStatus("Processing logs...");

    for (int i = 0; i < 100; i++)
    {
        // process log entry
        if (i == 25) log.LogError();
        if (i == 52) log.LogWarning();
    }

    log.LogStatus("Processing complete.");
    totalErrors = log.TotalErrors;
}

ref struct ErrorInfo
{
    public readonly string Message;
    public readonly DateTime TimeStamp;    
}

ref ErrorInfo GetErrorInfo()
{
    return new ErrorInfo { Message = "Error message", TimeStamp = DateTime.Now };
}

结语

C# 11 的改进使得在代码运行的过程中,结构体和引用类型的使用更加灵活,同时可以占用更少的内存。通过使用示例代码,实际操作一定会给开发者们带来更好的理解。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入浅析C# 11 对 ref 和 struct 的改进 - Python技术站

(0)
上一篇 2023年6月6日
下一篇 2023年6月6日

相关文章

  • CSRF在ASP.NET Core中的处理方法详解

    CSRF(Cross-Site Request Forgery)是一种常见的网络攻击,攻击者利用用户已经登录的身份,在用户不知情的情况下发送恶意请求。在 ASP.NET Core 中,可以采取以下措施来防止 CSRF 攻击: 步骤一:使用 Anti-forgery Token 在 ASP.NET Core 中,可以使用 Anti-forgery Token …

    C# 2023年5月17日
    00
  • C#键值对容器的介绍

    C#中的键值对容器主要指的是通过特定的键来访问元素的数据结构。它通常用于需要在某个特定条件下快速查找元素的情况,比如说搜索算法、缓存机制等。C#中的键值对容器有很多种,本文将从使用频率较高的Dictionary<TKey, TValue>和ConcurrentDictionary<TKey, TValue>两个类别来进行介绍。 Dic…

    C# 2023年6月1日
    00
  • ASP.NET Core – 缓存之分布式缓存

    分布式缓存是由多个应用服务器共享的缓存,通常作为访问它的应用服务器的外部服务进行维护。 分布式缓存可以提高 ASP.NET Core 应用的性能和可伸缩性,尤其是当应用由云服务或服务器场托管时。 与其他将缓存数据存储在单个应用服务器上的缓存方案相比,分布式缓存具有多个优势。 当分发缓存数据时,数据: 在多个服务器的请求之间保持一致(一致性)。 在进行服务器重…

    C# 2023年4月24日
    00
  • 关于C#连接SQL Server时提示用户登录失败的解决方法

    下面就是关于C#连接SQLServer时提示用户登录失败的解决方法的完整攻略: 1. 检查用户名和密码是否正确 第一步,你应该检查你提供的用户名和密码是否正确。在C#中,利用SqlConnectionStringBuilder类创建连接字符串,其中包括用户名和密码信息。示例代码如下: SqlConnectionStringBuilder builder = …

    C# 2023年5月14日
    00
  • C#超实用代码段合集

    C#超实用代码段合集攻略 简介 本文将介绍C#超实用代码段合集的使用方法,帮助读者更好地掌握这个工具并提高编程效率。 使用方法 下载安装 首先需要从github上下载C#超实用代码段合集的源码:https://github.com/justcoding121/C-Sharp-Snippets 源码下载完成后,使用Visual Studio打开CSharpSn…

    C# 2023年6月7日
    00
  • unity avprovideo插件的使用详解

    Unity AVProVideo插件的使用详解攻略 什么是Unity AVProVideo插件? AVProVideo是一款由Unity Asset Store上One of the Kind Productions公司开发的高级视频播放插件,它可以在Unity中轻松实现高品质和高性能的视频播放,支持多种视频格式和编码器(如H.264、H.265、VP8、V…

    C# 2023年6月3日
    00
  • asp.net C#生成和解析二维码的实例代码

    生成和解析二维码是现代开发中常见的需求,下面将介绍使用ASP.NET C#语言生成和解析二维码的实例代码。 生成二维码 使用C#语言生成二维码的方法有很多,我这里将介绍一种最常用的方法,即使用QRCoder库生成二维码。 安装QRCoder库 首先需要安装QRCoder库,在Visual Studio中打开项目,选择“工具”-“NuGet包管理器”-“程序包…

    C# 2023年5月31日
    00
  • ASP .NET中执行控件(如ImageButton、LinkButton等)命令不刷新页面

    ASP .NET中执行控件命令(如ImageButton、LinkButton等)不刷新页面的方案主要有两种: 使用UpdatePanel控件 UpdatePanel控件是ASP .NET中的异步刷新控件,它可以实现部分页面的异步刷新,从而使得页面局部刷新,不需要整个页面重新加载。在这种方式下,执行控件命令不会刷新整个页面,而是只会刷新UpdatePanel…

    C# 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部