深入浅析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日

相关文章

  • C#工程建立后修改工程文件名与命名空间操作

    C#工程的文件名与命名空间是非常重要的,因为它们直接影响了代码的可维护性与可重用性。在建立C#工程时,如果文件名与命名空间不符合要求,需要进行修改。下面是完整的操作攻略。 步骤一:建立工程并修改文件名 使用Visual Studio新建一个C#工程。 右键单击解决方案管理器中的工程节点,选择“重命名”。 输入新的文件名并按下Enter键。 在弹出的对话框中选…

    C# 2023年5月15日
    00
  • 使用C#编写15子游戏

    使用C#编写15子游戏攻略 1. 游戏规则 15子游戏,又称“拼图游戏”,是一个益智小游戏,目标是将1到15的数字方块移动到一个空白方块,使得所有数字方块按照从上到下,从左到右的顺序排列。每次只能移动相邻的一个数字方块,空白方块不能移动。最终达成目标则获得胜利。 2. 游戏实现 在C#中,我们可以使用Windows Form应用程序来实现15子游戏的界面。具…

    C# 2023年6月1日
    00
  • 在.NET Core类库中使用EF Core迁移数据库到SQL Server的方法

    在 .NET Core 类库中使用 EF Core 迁移数据库到 SQL Server 的方法 在 .NET Core 类库中使用 EF Core 迁移数据库到 SQL Server 是一种常见的操作。本攻略将介绍如何在 .NET Core 类库中使用 EF Core 迁移数据库到 SQL Server。 步骤 以下是在 .NET Core 类库中使用 EF…

    C# 2023年5月17日
    00
  • C# 使用匿名函数解决EventHandler参数传递的难题

    使用匿名函数可以很好地解决C#中使用EventHandler委托传递参数的难题。下面是在实现中应该遵循的步骤: 定义一个空的EventHandler委托,这个委托不需要接受任何参数。 public delegate void EventHandler(object sender, EventArgs e); 定义一个带有需要传递的参数的方法,可以是任何方法。…

    C# 2023年6月7日
    00
  • LINQ教程之LINQ操作语法

    欢迎来到本站的LINQ教程,今天我们将学习LINQ操作语法,帮助您更好地理解和使用LINQ。 什么是LINQ操作语法 LINQ操作语法(LINQ Query Syntax)是一种使用类似于SQL语句的查询语法快速查询数据的方法。 它是LINQ的一部分,使C#和VB.NET开发人员能够轻松地使用LINQ。 LINQ操作语法允许开发人员快速、易读地创建查询,包含…

    C# 2023年6月1日
    00
  • C#异常处理的一些经验和技巧

    C#异常处理的一些经验和技巧 概述 在编写C#程序时,避免不了会出现各种错误,例如:空引用、下标越界、文件不存在等等。这些错误如果不进行正确的处理,程序可能会崩溃甚至可能会损失一些敏感信息。本文将会为你介绍一些常见的C#错误处理技巧,帮助你更好地控制程序的异常情况。 try-catch语句 try-catch语句是C#语言中处理异常情况的一种常用技巧。try…

    C# 2023年5月15日
    00
  • C# 使用HttpClient上传文件并附带其他参数的步骤

    针对这个问题,我将按照以下结构来详细讲解如何使用C#的HttpClient上传文件并附带其他参数: 上传文件的基本步骤 附带其他参数的上传步骤 示例1:上传文件并附带一个简单参数 示例2:上传多个文件并附带多个参数 1. 上传文件的基本步骤 要使用HttpClient上传文件,需要进行以下步骤: 创建一个实例的HttpClient类 构建一个实例的Multi…

    C# 2023年6月1日
    00
  • 如何合并多个 .NET 程序集

    合并多个 .NET 程序集的操作主要包括以下几步: 安装 ILmerge 工具 ILmerge 是一个由微软开发的 .NET 程序集合并工具,可以从 NuGet 上下载和安装。 Install-Package ILmerge 打开命令提示符或 PowerShell在安装完成后,通过打开命令提示符或 PowerShell 等终端窗口,进入想要合并的程序集所在的…

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