C# 8.0 中的 Disposable ref structs(可处置的 ref 结构)

c#,disposable,ref,structs,处置,结构 · 浏览次数 : 162

小编点评

**官方文档解释:** ```csharp  ref 修饰符声明的 struct 可能无法实现任何接口,因此无法实现 IDisposable。 ``` **说明:** * `ref` 修饰符用于声明一个引用类型的变量。 * `struct` 是一个结构类型,是 C# 中一种特殊的类型。 * `IDisposable` 接口用于定义一个对象的生命周期方法,当对象不再需要时,将其资源释放。 * `Dispose()` 方法用于清理对象资源。 * 由于 `ref` 结构类型无法实现接口,因此它无法实现 `IDisposable` 接口。 * 这意味着在使用 `ref` 结构类型之前,必须为其分配内存并确保其资源得到释放。 **示例:** 虽然 `ref` 结构类型无法实现 `IDisposable` 接口,但我们可以通过在结构中添加 `Dispose()` 方法来处理资源。例如: ```csharp public struct Book : IDisposable { public void Dispose() { Console.WriteLine(\"Book is disposed.\"); } } ``` 在使用 `Book` 结构时,可以使用 `using` 语句,自动调用 `Dispose()` 方法。 **其他实例:** * `internal ref struct ValueUtf8Converter` 和 `internal ref struct RegexWriter` 是 `IDisposable` 接口的实现类。 * 这些类使用 `Dispose()` 方法来清理其资源。

正文

官方文档中的解释:

  用 ref 修饰符声明的 struct 可能无法实现任何接口,因此无法实现 IDisposable。 因此,要能够处理 ref struct,它必须有一个可访问的 void Dispose() 方法。 此功能同样适用于 readonly ref struct 声明。

由于没有示例用法,开始一直看着摸不着头脑,因此在网上找了个实例,以供参考,希望有助于你我的理解。

ref 结构体不能实现接口,当然也包括 IDisposable,因此我们不能在 using 语句中使用它们,如下错误实例:

class Program
{
   static void Main(string[] args)
   {
      using (var book = new Book())
         Console.WriteLine("Hello World!");
   }
}
// 报错内容:Error CS8343 'Book': ref structs cannot implement interfaces
ref struct Book : IDisposable
{
   public void Dispose()
   {
   }
}

现在我们可以通过在ref结构中,添加Dispose方法,然后 Book 对象就可以在 using 语句中引用了。

class Program
{
   static void Main(string[] args)
   {
      using (var book = new Book())
      {
         // ...
      }
    }
}
ref struct Book
{
   public void Dispose()
   {
   }
}

由于在 C# 8.0 版本 using 语句的简化,新写法:(book 对象会在当前封闭空间结束前被销毁)

class Program
{
   static void Main(string[] args)
   {
      using var book = new Book();
      // ...
   }
}

另外两个实例:

internal ref struct ValueUtf8Converter
{
   private byte[] _arrayToReturnToPool;
   ...
   public ValueUtf8Converter(Span<byte> initialBuffer)
   {
      _arrayToReturnToPool = null;
   }
   public Span<byte> ConvertAndTerminateString(ReadOnlySpan<char> value)
   {
      ...
   }
   public void Dispose()
   {
      byte[] toReturn = _arrayToReturnToPool;
      if (toReturn != null)
      {
         _arrayToReturnToPool = null;
         ArrayPool<byte>.Shared.Return(toReturn);
      }
   }
}
internal ref struct RegexWriter
{
   ...
   private ValueListBuilder<int> _emitted;
   private ValueListBuilder<int> _intStack;
   ...
   public void Dispose()
   {
      _emitted.Dispose();
      _intStack.Dispose();
   }
}

参考自:Disposable ref structs in C# 8.0

与C# 8.0 中的 Disposable ref structs(可处置的 ref 结构)相似的内容:

C# 8.0 中的 Disposable ref structs(可处置的 ref 结构)

由于官方文档没有示例用法,开始一直看着摸不着头脑,因此在网上找了个实例,以供参考,希望有助于你我的理解。

热更学习笔记--toLau中lua脚本对C#中枚举和数组的访问

[8]Lua脚本调用C#中的枚举学习 --调用枚举类型 print(" toLua中调用C#中枚举类型 ") PrimitiveType = UnityEngine.PrimitiveType local cubeObj = GameObject.CreatePrimitive(PrimitiveT

算法学习笔记(8.0): 网络流前置知识

网络流基础 网络流合集链接:网络流 网络 $G = (V, E)$ 实际上是一张有向图 对于图中每一条有向边 $(x, y) \in E$ 都有一个给定的容量 $c(x, y)$ 特别的,若 $(x,y) \notin E$ , 则 $c(x, y) = 0$ 图中还有两个指定的特殊结点,$S, T

[转帖]【JVM】类文件结构

Class文件的定义 一组以8字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑排列在class文件中,中间没有任何分隔符,这使得class文件中存储的内容几乎是全部程序运行的程序。 注:Java虚拟机规范规定,Class文件格式采用类似C语言结构体的伪结构来存储数据,这种结构只有两种数据类型:

C++ 初始化列表(Initialization List)

请注意以下继承体系中各class的constructors写法: 1 class CPoint 2 { 3 public: 4 CPoint(float x=0.0) 5 :_x(x){} 6 7 float x() {return _x;} 8 void x(float xval){_x=xval

8KB的C#贪吃蛇游戏热点答疑和.NET7版本

在之前的一篇文章《看我是如何用C#编写一个小于8KB的贪吃蛇游戏》中,介绍了在.NET Core 3.0的环境下如何将贪吃蛇游戏降低到8KB。不过也有很多小伙伴提出了一些疑问和看法,主要是下面这几个方面: .NET Core 3.0可以做到这么小,那么.NET7表现会不会更好? 不敢在生产中用这样的

[转帖]jmeter实现分布式压测

分布式实现的前提条件: 1.master机器和奴隶机的jmeter要一致 a. jmeter版本要一致 b.jdk主要版本要一致,比如都是jdk1.8,后面的小版本不一样不影响 c.jmeter脚本中csv文件要一致(特别注意csv路径,建议csv路径使用相对路径,放在脚本的同级目录) d.jmet

C#使用SendMessage进行进程间通讯

最近公司有个需求是,拖动文件到桌面图标上,自动打开文件。那么只需在OnStartup事件中通过StartupEventArgs获取文件名然后进行操作即可。操作之后发现当软件已经启动了(单例运行),那么将无法将参数传给业务层。原因是因为跨进程了,那么我们可以通过窗口句柄的方式来进行通讯。 1 publ

[转帖]echo 输出不换行-e \c

http://www.my889.com/i/1952 在shell中,echo输出会自动换行。有时候在循环中不希望echo输出换行。代码实现如下: 1 echo -e " \c" # -e 表示开启转义, \c表示不换行 脚本: 1 2 3 4 5 6 7 8 9 #!/bin/bash i=1

C# 8.0 添加和增强的功能【基础篇】

.NET Core 3.x 和 .NET Standard 2.1 支持 C# 8.0。本文对此版本的更新内容做了简单的记录,希望有助于你我的理解。