首先,在实际问题之前,有一个小免责声明:
我知道有很多关于 `sizeof` 操作符和 `Marshal.SizeOf` 方法之间的区别的封闭/重复问题,而且我确实理解两者之间的区别。这里我谈论的是新的 `Unsafe` 类中的 `SizeOf` 方法。
因此,我不确定我理解这两个操作之间的实际区别,以及在特定情况下在结构体/类上使用该方法是否存在特定差异。
`sizeof` 操作符接受一个类型名称并返回分配时应占用的托管字节数(例如,`Int32` 将返回 4)。
另一方面,`Unsafe.SizeOf` 方法像 `Unsafe` 类中的所有其他方法一样在 IL 中实现,并且查看代码后,以下是它所做的事情:
现在,如果我没错的话,代码只是调用
另外,我看到该方法还在第一行分配了一个无用的对象(
我的问题是:
我知道有很多关于 `sizeof` 操作符和 `Marshal.SizeOf` 方法之间的区别的封闭/重复问题,而且我确实理解两者之间的区别。这里我谈论的是新的 `Unsafe` 类中的 `SizeOf` 方法。
因此,我不确定我理解这两个操作之间的实际区别,以及在特定情况下在结构体/类上使用该方法是否存在特定差异。
`sizeof` 操作符接受一个类型名称并返回分配时应占用的托管字节数(例如,`Int32` 将返回 4)。
另一方面,`Unsafe.SizeOf` 方法像 `Unsafe` 类中的所有其他方法一样在 IL 中实现,并且查看代码后,以下是它所做的事情:
.method public hidebysig static int32 SizeOf<T>() cil managed aggressiveinlining
{
.custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 )
.maxstack 1
sizeof !!T
ret
}
现在,如果我没错的话,代码只是调用
sizeof !!T
这与sizeof(T)
相同(使用类型名T
调用sizeof
运算符),那么它们两个难道不完全等效吗?另外,我看到该方法还在第一行分配了一个无用的对象(
NonVersionableAttribute
),那么这是否也会导致少量内存被堆分配?我的问题是:
可以安全地说这两种方法是完全等价的,因此最好使用经典的
sizeof
运算符,因为它还避免了在SizeOf<T>
方法中分配该属性吗?在这一点上,SizeOf<T>
方法是添加到Unsafe
类中仅仅为了方便吗?
.custom
语句只是告诉您该方法存在自定义属性。由于自定义属性只是元数据,因此它们不参与常规方法调用。 - thehennyy