C# ref struct和ref class的特点

本文探讨了C#中的ref struct特性,这种类型仅在栈上分配,防止GC开销和装箱拆箱,提高性能。ref struct内部的ref成员确保数据在栈上的语义完整,避免内存泄漏。通过Span处理连续内存数据,例如处理图片原始格式,提升效率。ref class则涉及C++/CLI中与CLR管理的引用类型相关的内容,用于创建可从C#访问的类。
摘要由CSDN通过智能技术生成

①C#中的ref struct是一种特殊的结构类型,它只能在栈上分配,不能逃逸到托管堆上。这样可以避免垃圾回收和装箱拆箱的开销,提高性能。

②在ref struct里面以ref方式声明一个struct成员的作用是让该成员也只能在栈上分配,不能被复制或传递给其他变量。这样可以保持ref struct的语义和约束,防止内存泄漏或不安全操作。

③ref struct 主要是用来减少GC,比如声明变量的时候可以用它来在不同对象中传递指向连续内存地址的数据,虽然会降低灵活性,不如List之类的工具功能强大,但在处理一些特定的数据的时候能给你更高的效率。

比如图片,如果已知图片的原始格式,就可以通过 Span<byte> 对内存中 Image 类所提供的地址来获取这个连续的 byte[] 的指针,并通过 Span 的方法可以进行数据拆分,比如从 32 ARGB 中提取每个 ARGB 的 Span<byte> ( 依然是个指向原始数据片段的指针 )
就不需要用如 - var argb = byte[4] 这种变量来降低执行效率,因为用完之后 argb 会被GC。

比如在循环中你要对每个颜色进行运算,那么可以通过直接划分两个连续的内存片段,然后对 Span 进行计算。计算过程可以使用 buffer 也可以直接创建个大的中间层来提高效率 (但会占用更多内存)

ref 结构类型 C#参考 ref 结构类型 - C# 参考 | Microsoft Learn

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C#中调用EnumDisplayMonitors和GetMonitorInfo函数获取屏幕大小,您可以使用以下代码: ```csharp using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Drawing; class Program { [DllImport("user32.dll")] static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, EnumMonitorsDelegate lpfnEnum, IntPtr dwData); [DllImport("user32.dll")] static extern bool GetMonitorInfo(IntPtr hMonitor, ref MonitorInfoEx lpmi); delegate bool EnumMonitorsDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref Rect lprcMonitor, IntPtr dwData); [StructLayout(LayoutKind.Sequential)] public struct Rect { public int left; public int top; public int right; public int bottom; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct MonitorInfoEx { public int cbSize; public Rect rcMonitor; public Rect rcWork; public uint dwFlags; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string szDevice; } static bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, ref Rect lprcMonitor, IntPtr dwData) { MonitorInfoEx mi = new MonitorInfoEx(); mi.cbSize = Marshal.SizeOf(mi); GetMonitorInfo(hMonitor, ref mi); int width = mi.rcMonitor.right - mi.rcMonitor.left; int height = mi.rcMonitor.bottom - mi.rcMonitor.top; Console.WriteLine("Screen width: " + width + ", height: " + height); return true; } static void Main(string[] args) { EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, MonitorEnumProc, IntPtr.Zero); } } ``` 该代码使用EnumDisplayMonitors函数枚举所有屏幕,并使用GetMonitorInfo函数获取每个屏幕的大小。然后将屏幕的宽度和高度打印到控制台中。注意,该示例代码使用了一些Windows API结构体和方法,需要在代码中进行声明和引用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最强玩者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值