C#结构体拆箱可能为空(CS8605):寻求无需转类的替代方案
解决Marshal.PtrToStructure转换struct时的CS8605警告(无需转为class)
在VS Code的C# Dev Kit中,使用struct类型POLICY_DNS_DOMAIN_INFO调用Marshal.PtrToStructure转换指针时,会触发「Unboxing a possibly null value. (CS8605)」警告。无需将struct改为class,以下两种简单方案可以解决问题:
方案1:使用泛型版本Marshal.PtrToStructure<T>
泛型方法针对值类型(struct)会直接返回实例,不会涉及拆箱操作,编译器不会产生空值警告。
保留原struct定义,修改转换代码:
// 保持struct不变 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct POLICY_DNS_DOMAIN_INFO { public LSA_UNICODE_STRING Name; public LSA_UNICODE_STRING DnsDomainName; public LSA_UNICODE_STRING DnsForestName; public GUID DomainGuid; public IntPtr pSID; } // ... 其他代码省略 ... resultQueryPolicy = LsaQueryInformationPolicy( policyHandle, POLICY_INFORMATION_CLASS.PolicyDnsDomainInformation, out IntPtr infoStructure ); winErrorCode = LsaNtStatusToWinError(resultQueryPolicy); if (winErrorCode == 0) { // 使用泛型版本转换,无CS8605警告 POLICY_DNS_DOMAIN_INFO domain = Marshal.PtrToStructure<POLICY_DNS_DOMAIN_INFO>(infoStructure); // ... 后续处理代码 ... }
方案2:临时抑制CS8605警告
如果必须使用非泛型版本的Marshal.PtrToStructure,可以在转换代码块前后添加警告抑制指令。由于已经通过winErrorCode == 0确认指针有效,无需担心空值问题。
if (winErrorCode == 0) { #pragma warning disable CS8605 POLICY_DNS_DOMAIN_INFO domain = (POLICY_DNS_DOMAIN_INFO)Marshal.PtrToStructure(infoStructure, typeof(POLICY_DNS_DOMAIN_INFO)); #pragma warning restore CS8605 // ... 后续处理代码 ... }
警告原因说明
非泛型Marshal.PtrToStructure返回object类型,当转换为值类型struct时,编译器无法确定返回的object是否为null,因此触发拆箱空值警告。而泛型版本针对值类型做了优化,直接返回struct实例,不存在空值风险,所以不会触发警告。
内容的提问来源于stack exchange,提问作者howdoicode
相关产品推荐
相关产品推荐

