You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8中Marshal.SizeOf<T>泛型重载的行为不一致问题

Marshal.SizeOf泛型重载的行为不一致问题(基于.NET 8运行时)

我发现Marshal.SizeOf<T>方法的泛型重载存在行为不一致问题,以下仅讨论泛型重载场景:

问题1:Marshal.SizeOf<T>()支持范围过窄

考虑以下代码:

using System.Collections.Generic;
using System.Runtime.InteropServices;

// ...

int size1a = Marshal.SizeOf<KeyValuePair<int, int>>(KeyValuePair.Create(123, 456));  // 正常,返回8
int size1b = Marshal.SizeOf<KeyValuePair<int, int>>(default);                        // 正常,返回8
int size2 = Marshal.SizeOf<KeyValuePair<int, int>>();                                // 抛出异常?!

说明:KeyValuePair<TKey, TValue>是包含两个非静态字段(类型为TKey和TValue)的struct。当TKey和TValue均为无托管字段的int时,KeyValuePair<int, int>不含引用类型成员,属于“非托管类型”。

预期:size2应能像size1a和size1b一样计算出大小(值为8)

实际:抛出ArgumentException,提示“T不能是泛型类型”

疑问:为何接收参数的重载能正常计算大小,无参重载却无法做到?

注意:自C# 7.3起,封闭类型KeyValuePair<int, int>可满足where TSomething : unmanaged泛型约束,自然预期其大小可被计算。

问题2:Marshal.SizeOf<T>(T structure)支持范围过宽

在KeyValuePair<,>中使用托管类型:

using System.Collections.Generic;
using System.Runtime.InteropServices;

// ...

int size3 = Marshal.SizeOf<KeyValuePair<string, string>>(KeyValuePair.Create("arbitrarily long text", "can go in here"));

预期:由于该类型/实例持有托管对象引用(此处为System.String类),调用应抛出异常

实际:调用成功,返回值取决于编译平台,例如x86平台返回8(==4+4),x64平台返回16(==8+8)等

疑问:为何返回值为运行时引用宽度的两倍?

此场景在.NET Framework 4.8中表现正常:尝试计算size3会抛出指定参数异常。因此问题2是.NET 8新增的异常行为。

请问我是否应将这些问题报告为.NET的bug,还是我忽略了某些细节?


内容的提问来源于stack exchange,提问作者Jeppe Stig Nielsen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 00:32:50