gpt4 book ai didi

c# - sizeof(T) 和 Unsafe.SizeOf() 有什么区别?

转载 作者:IT王子 更新时间:2023-10-29 04:08:15 24 4
gpt4 key购买 nike

首先,在实际问题之前的一个小免责声明:

I know there are a lot of closed/duplicate questions regarding the difference between the sizeof operator and the Marshal.SizeOf<T> method, and I do understand the difference between the two. Here I'm talking about the SizeOf<T> method in the new Unsafe class

所以,我不确定我是否理解这两个操作之间的实际区别,以及在特定结构/类上使用该方法时是否存在特定区别。

sizeof运算符采用类型名称并返回分配时应该占用的托管字节数(例如,Int32 将返回 4)。

Unsafe.SizeOf<T>另一方面,方法像 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 !!Tsizeof(T) 相同(用类型名称 sizeof 调用 T 运算符),那么它们两个不是完全等价的吗?

此外,我看到该方法还在第一行分配了一个无用的对象(NonVersionableAttribute),那么这不会导致少量内存也被分配到堆中吗?

我的问题是:

Is it safe to say that the two methods are perfectly equivalent and that therefore it is just better to use the classic sizeof operator, as that also avoid the allocation of that attribute in the SizeOf<T> method? Was this SizeOf<T> method added to the Unsafe class just for convenience at this point?

最佳答案

虽然这个方法确实只使用 sizeof IL 指令 - 与常规的 sizeof 运算符有所不同,因为这个运算符不能应用于任意类型:

Used to obtain the size in bytes for an unmanaged type. Unmanaged types include the built-in types that are listed in the table that follows, and also the following:

Enum types

Pointer types

User-defined structs that do not contain any fields or properties that are reference types

如果您尝试编写 Unsafe.SizeOf 的模拟 - 它不会工作:

public static int SizeOf<T>()
{
// nope, will not compile
return sizeof(T);
}

因此 Unsafe.SizeOf 解除了 sizeof 运算符的限制,并允许您对任意类型(包括引用类型)使用 IL sizeof 指令它将返回引用大小)。

至于您在 IL 中看到的属性构造——这并不意味着每次调用都会实例化属性——这只是将属性与各种成员相关联的 IL 语法(本例中为方法)。

例子:

public struct Test {
public int Int1;
}

static void Main() {
// works
var s1 = Unsafe.SizeOf<Test>();
// doesn't work, need to mark method with "unsafe"
var s2 = sizeof(Test);
}

另一个例子:

public struct Test {
public int Int1;
public string String1;
}


static unsafe void Main() {
// works, return 16 in 64bit process - 4 for int, 4 for padding, because
// alignment of the type is the size of its largest element, which is 8
// and 8 for string
var s1 = Unsafe.SizeOf<Test>();
// doesn't work even with unsafe,
// cannot take size of variable of managed type "Test"
// because Test contains field of reference type (string)
var s2 = sizeof(Test);
}

关于c# - sizeof(T) 和 Unsafe.SizeOf<T>() 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47922524/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com